首次在nextjs上加载动态路由时获取404

时间:2020-02-05 19:50:51

标签: reactjs next.js

我正在尝试创建一个博客页面来测试nextjs,并为帖子创建一条动态路线,该路线将从Contentful中检索。从主页导航并单击到next/router <Link />组件时,博客文章正确加载,但是如果获得URL并尝试直接从浏览器地址栏中加载页面,则得到404。

复制步骤:

 1. git clone https://github.com/zeit/next-learn-demo.git
 2. cd next-learn-demo/8-deploying
 3. yarn
 4. next build && next export
 5. cd out
 6. serve
 7. Navigate to http://localhost:5000/p/learn-nextjs
 8. See 404

这是NextJS的限制吗(在文档中找不到与之相关的任何内容)还是我们需要配置其他内容?

3 个答案:

答案 0 :(得分:3)

真正的问题是,导出sample_nr应用会使其生成静态HTML文件。即使它仍能够在呈现页面之前请求数据,但可用路径集并不是动态的(它们是在SELECT Count(tbl_demo.unique_id) AS CountOfunique_id ,tbl_res.result FROM ( tbl_demo INNER JOIN tbl_samples ON tbl_demo.unique_id = tbl_samples.unique_id ) INNER JOIN tbl_res ON tbl_samples.sample_nr = tbl_res.sample_nr GROUP BY tbl_res.result; 命令期间生成的)。请参见此docs和此example

基于此,我有2种可能的解决方案:

  • 每次在Contentful中发布新博客帖子时,生成一个Webhook来触发next命令;
  • 避免导出我的next export应用,并托管将处理动态路由的Node服务器。

答案 1 :(得分:2)

那是因为当您直接访问链接或刷新页面时,它会在路径末尾添加一个斜杠。 next.js无法识别任何这样的路由。要解决此问题,我希望应该有一种最简单的方法。但是,您可以使用custom server进行此操作。这是一个示例:

server.get("/about/", (req, res) => {
  return app.render(req, res, "/about")
});

希望这会对您有所帮助。

答案 2 :(得分:1)

为了扩展@Minoru 提供的答案,Next 官方文档在此 example 中涵盖了这种情况。

使用 getStaticPathsgetStaticProps 允许您在构建时创建动态页面,避免 404。

动态页面的示例代码:

import { GetStaticPaths, GetStaticProps } from 'next';

const Post = ({ post }) => {
    const { id, content } = post;

    return (
        <div>
            <h1>Post {id}</h1>
            <p>{content}</p>
        </div>
    );
};

export const getStaticPaths: GetStaticPaths = async () => {
    // Get all posts via API, file, etc.
    const posts = [{ id: '1' }, { id: '2' }, { id: '3' }, { id: '4' }, { id: '5' }]; // Example
    const paths = posts.map(post => ({
        params: { id: post.id },
    }));
    return { paths, fallback: false };
};

export const getStaticProps: GetStaticProps = async context => {
    const postId = context.params?.id || '';
    // Get post detail via API, file, etc.
    const post = { id: postId, content: `I'm the post with id ${postId}!` }; // Example
    return { props: { post } };
};

export default Post;

使用 next build && next export 构建网站时,我们将在 out 文件夹中看到 Next 创建了每个帖子页面

posts in out folder

然后,当您导航到 /posts/3/ 时,您将看到 ID 为 3 的帖子

post with id 3 page

作为参考,此 docs 页面包含此案例和许多其他用例。