Nextjs页面刷新后进入404

时间:2019-02-21 20:02:42

标签: next.js

我正在将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复制并粘贴到新窗口中,则得到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;

2 个答案:

答案 0 :(得分:1)

您可以在项目根目录的名为 next.config.js 的文件中尝试这些操作

module.exports = {
  exportTrailingSlash: true
}

选中this link

答案 1 :(得分:0)

这是因为,当您使用next/link组件时,href道具具有指向页面的“真实” URL,并带有用于设置商品ID的查询参数。这意味着Next.js可以在客户端(浏览器)上加载用于数据查询的参数的正确页面(您的product.js页面)。

但是,当您从服务器加载时,无论是通过重新加载页面还是在新窗口中打开页面,Next.js都不知道要加载哪个页面,在这种情况下,我认为它将尝试找到文件{{ 1}},当然不存在。

如果要使用这些类型的URL,还必须确保将请求路由到服务器上的正确页面文件(./pages/new-releases/product/Plattan-2-Bluetooth.js)。您可以通过创建自定义服务器来做到这一点。 Next.js存储库中有一堆examples,其中一个使用Express。在该网站的“学习”部分的名为Server Side Support for Clean URLs

的教程中也对此进行了介绍。

如果您决定使用Express,您将得到类似以下的内容:

./pages/product.js

这将呈现产品页面,并且您将在server.get('/:collection/product/:productUrl', (req, res) => { return app.render(req, res, '/product', { productUrl: req.params.productUrl}) }) 中的productUrl对象上拥有query。当然,现在您需要使用该数据而不是产品ID来获取数据。