Link Search Menu Expand Document

NextJS

Data Fetching

Runs at build time: getStaticProps (Static Generation): Fetch data at build time.

Runs on render: getStaticPaths (Static Generation): Specify dynamic routes to pre-render based on data.

Runs on refresh: getServerSideProps (Server-side Rendering): Fetch data on each request.

Example of having nested routes

This is for when you want to have dynamic routes that are more than a posts/[slug].js path, so what do I mean by that, lets take a look at the typical file structure on the Next.js example sites:

next-js-project/
├─ content/
│  ├─ post-one.md
│  ├─ post-two.md
│  └─ post-three.md
├─ pages/
│  ├─ posts/[slug].js
│  └─ index.js

That will give you the path to the files like:

localhost:3000/posts/post-one
localhost:3000/posts/ost-two
localhost:3000/posts/post-three

That's fine n' all but what if you have content you want to link with your Markdown posts like images, that content folder will get a bit difficult to reason about once you get a lot of content in there.

With Gatsby I have always done a file structure in this format:

content/posts/yyyy/mm/dd/post-title/index.mdx

So I went about trying to do that with the Next.js examples.

Thanks to Eka in the Party Corgi Discord for pointing out the section in the basic features of the Next.js documentation, it wasn't entirely clear to me what catch all routes was.

:lib/posts.js

import globby from 'globby'

const postsDirectory = './content/posts'

export async function getPostPaths() {
  const files = await globby(postsDirectory, {
    expandDirectories: { extensions: ['md*'] },
  })

  return await files
}

export async function getPostSlugs() {
  const files = await getPostPaths()

  const paths = files.map(path => {
    const split = path.split(`/`)
    // remove `content/posts` and `index.md*`
    const removedIndexFile = split.splice(2, split.length - 3)

    return {
      params: {
        slug: removedIndexFile,
      },
    }
  })

  return {
    paths,
    fa,
  }
}

:pages/[...slug].js

import { getPostSlugs } from '../lib/posts'

export default function Post({ slug }) {
  console.log('=====================')
  console.log(`slug::: ${slug}`)
  console.log('=====================')
  return <Layout>yo</Layout>
}

export const getStaticPaths = async () => {
  return await getPostSlugs()
}

export const getStaticProps = async ({ params: { slug } }) => {
  return {
    props: { slug },
  }
}

Children

  1. Resources