Nextjs 页面在刷新时转到 404
Nextjs page goes to 404 on refresh
我正在使用 nextjs 和 graphql 进行 shopify POC。
我有一个显示产品列表的组件,其中包含指向产品页面的链接
<Link
as={`${handle}/product/${url}`}
href={`/product?id=${item.id};`}>
<a>{item.title}</a>
</Link>
handle 是集合名称,因此浏览器中的 url 看起来像
http://localhost:3000/new-releases/product/Plattan-2-Bluetooth 但在幕后,它实际上只是使用一个名为产品的页面,我正在传递产品 ID。
现在在 product.js(粘贴在下面)中,我正在获取 id 的查询字符串值并执行另一个查询以获取产品。一切正常,但如果我点击刷新或将 url 复制并粘贴到新的 window 中,我会得到 404。
我知道这与路由有关,但我不确定我需要做什么来解决这个问题。谢谢
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Query } from 'react-apollo';
import gql from 'graphql-tag';
class product extends Component {
static async getInitialProps({query}) {
console.log("query", query)
return query ? { id: query.id.replace(';', '') } : {}
}
render() {
const PRODUCT_FRAGMENT = gql`
fragment ProductPage on Product {
title
description
descriptionHtml
id
images(first: 10, maxWidth: 600) {
edges {
node {
id
altText
originalSrc
}
}
}
}
`;
const PRODUCT_FETCH_QUERY = gql`
query PRODUCT_FETCH_QUERY {
node(id: "${this.props.id}") {
__typename
...ProductPage
}
}
${PRODUCT_FRAGMENT}
`;
return (
<div>
<Query query={PRODUCT_FETCH_QUERY}>
{({ data, error, loading }) => {
console.log("data", data)
if (loading) return <p>Loading...</p>
if (error) return <p>Error: {error.message}</p>
return null}
}
</Query>
</div>
);
}
}
product.propTypes = {
};
export default product;
这是因为当您使用 next/link
组件时,href
属性具有 "real" URL 到带有项目 ID 集查询参数的页面。这意味着在客户端(浏览器)上,Next.js 可以使用您的数据查询参数加载正确的页面(您的 product.js 页面)。
但是当您从服务器加载时,通过重新加载页面或在新 window 中打开它,Next.js 不知道要加载哪个页面,在这种情况下我认为它将尝试查找文件 ./pages/new-releases/product/Plattan-2-Bluetooth.js
,当然该文件不存在。
如果您想要这些类型的 URL,您必须确保请求也被路由到服务器上正确的页面文件 (./pages/product.js
)。您可以通过创建自定义服务器来做到这一点。有一堆examples in the Next.js repo including one using Express. This is also covered in the "Learn" section of there website in a tutorial called Server Side Support for Clean URLs
如果您决定使用 Express,您将得到如下结果:
server.get('/:collection/product/:productUrl', (req, res) => {
return app.render(req, res, '/product', { productUrl: req.params.productUrl})
})
这将呈现产品页面,您将在 getInitialProps()
中的 query
对象上获得 productUrl
。当然,现在您需要使用它而不是产品 ID 来获取数据。
您可以在项目根目录中名为 next.config.js 的文件中尝试这些
module.exports = {
exportTrailingSlash: true
}
我正在使用 nextjs 和 graphql 进行 shopify POC。
我有一个显示产品列表的组件,其中包含指向产品页面的链接
<Link
as={`${handle}/product/${url}`}
href={`/product?id=${item.id};`}>
<a>{item.title}</a>
</Link>
handle 是集合名称,因此浏览器中的 url 看起来像 http://localhost:3000/new-releases/product/Plattan-2-Bluetooth 但在幕后,它实际上只是使用一个名为产品的页面,我正在传递产品 ID。
现在在 product.js(粘贴在下面)中,我正在获取 id 的查询字符串值并执行另一个查询以获取产品。一切正常,但如果我点击刷新或将 url 复制并粘贴到新的 window 中,我会得到 404。
我知道这与路由有关,但我不确定我需要做什么来解决这个问题。谢谢
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Query } from 'react-apollo';
import gql from 'graphql-tag';
class product extends Component {
static async getInitialProps({query}) {
console.log("query", query)
return query ? { id: query.id.replace(';', '') } : {}
}
render() {
const PRODUCT_FRAGMENT = gql`
fragment ProductPage on Product {
title
description
descriptionHtml
id
images(first: 10, maxWidth: 600) {
edges {
node {
id
altText
originalSrc
}
}
}
}
`;
const PRODUCT_FETCH_QUERY = gql`
query PRODUCT_FETCH_QUERY {
node(id: "${this.props.id}") {
__typename
...ProductPage
}
}
${PRODUCT_FRAGMENT}
`;
return (
<div>
<Query query={PRODUCT_FETCH_QUERY}>
{({ data, error, loading }) => {
console.log("data", data)
if (loading) return <p>Loading...</p>
if (error) return <p>Error: {error.message}</p>
return null}
}
</Query>
</div>
);
}
}
product.propTypes = {
};
export default product;
这是因为当您使用 next/link
组件时,href
属性具有 "real" URL 到带有项目 ID 集查询参数的页面。这意味着在客户端(浏览器)上,Next.js 可以使用您的数据查询参数加载正确的页面(您的 product.js 页面)。
但是当您从服务器加载时,通过重新加载页面或在新 window 中打开它,Next.js 不知道要加载哪个页面,在这种情况下我认为它将尝试查找文件 ./pages/new-releases/product/Plattan-2-Bluetooth.js
,当然该文件不存在。
如果您想要这些类型的 URL,您必须确保请求也被路由到服务器上正确的页面文件 (./pages/product.js
)。您可以通过创建自定义服务器来做到这一点。有一堆examples in the Next.js repo including one using Express. This is also covered in the "Learn" section of there website in a tutorial called Server Side Support for Clean URLs
如果您决定使用 Express,您将得到如下结果:
server.get('/:collection/product/:productUrl', (req, res) => {
return app.render(req, res, '/product', { productUrl: req.params.productUrl})
})
这将呈现产品页面,您将在 getInitialProps()
中的 query
对象上获得 productUrl
。当然,现在您需要使用它而不是产品 ID 来获取数据。
您可以在项目根目录中名为 next.config.js 的文件中尝试这些
module.exports = {
exportTrailingSlash: true
}