Search code examples
next.jsdirectory-structurefile-structuredynamic-url

How to properly map my markdown content to dynamic URLs in Next.js?


I'd like to have the following URL structure:

URL Role
/ markdown contents of /index.md
/about markdown contents of /about.md
/cookies markdown contents of /cookies.md
/privacy-policy markdown contents of /privacy-policy.md
/category1 category1 index page
/category1/post1 markdown contents of /category1/post1.md
/category1/post2 markdown contents of /category1/post2.md
/category2 category2 index page
/category2/post1 markdown contents of /category2/post1.md
/category2/post2 markdown contents of /category2/post2.md

I'd like to avoid having to create separate .js files for my content in the root directory (so no /about.js, /cookies.js, etc), but if I try something like this...

pages/
    index.js
    [root_article_id].js
    [category]/
        index.js
        [category_article_id].js

... then Next.js complains because it cannot decide when I request the URL /about whether if it should use [category]/index.js or [root_article_id].js, even though I feel the latter should be called first, and if it doesn't want to deal with the request (i.e. if there's no about.md in the root of my markdown directory), then it should fall back to [category]/index.js, which still could pass the request through to the 404 handler if [category].js spits it out.

What's the correct way of structuring Next.js files for this? Do I really need to have separate .js files for my markdown files in the root content directory?


Solution

  • What's the correct way of structuring Next.js files for this? Do I really need to have separate .js files for my markdown files in the root content directory?

    This is the easiest way since you have to somehow tell nextjs what pages you want to be articles. However, if want to avoid doing it, you can do it with rewrites.

    If you know all articles (or categories), this is what you need in your next.config.js:

    module.exports = {
      rewrites() {
        return [
          {
            source: "/about",
            destination: "/article/about",
          },
          {
            source: "/cookies",
            destination: "/article/cookies",
          },
          {
            source: "/privacy-policy",
            destination: "/article/privacy-policy",
          },
        ];
      },
    };
    

    And then make article/[root_article_id] page. Note that rewrite does not mean redirect. The page will be available in /about but nextjs will handle it like the request was to /article/about. This means that these pages will also be available from article/about, but this can probably be prevented if for some reason necessary.

    Whether you should do rewrites for articles or categories depends on which one is dynamic. If neither one is really dynamic in a sense that you know all the possible values, you should pick the one with less possible values.

    If both of categories and articles are dynamic, you need to do the rewrites with middleware (beta). In your middleware you get the req and you somehow need to decide if the requested url is an article or a category page. How this is done obviously depends on where and how you store your data.