Programmatically creating links for static pages with next.js

Viewed 362

For a next.js pages directory that contains a bunch of static pages (not dynamic routes!)…

pages/
├── index.tsx
├── SomePage.tsx
├── someOtherPage
│   └── index.tsx
├── someOtherOtherPage
│   └── index.tsx
└── someOtherOtherOtherPage
    └── index.tsx

…is it possible to create links at build time, rather than typing all out manually?

I.e.: not this:

// index.js
<ol>
  <li>
    <Link href="/somePage/">Some Page</Link>
  </li>
  <li>
    <Link href="/someOtherPage/">Some Other Page</Link>
  </li>
  …
</ol>

…but something comparable to Gatsby's approach that uses Graphql nodes as location props:

// Example Gatsby.js page

const IndexPage = ({
  data: {
    allMarkdownRemark: { edges },
  },
}) => {
  const Posts = edges
    .filter(edge => !!edge.node.frontmatter.date) // You can filter your posts based on some criteria
    .map(edge => <PostLink key={edge.node.id} post={edge.node} />)

  return <div>{Posts}</div>
}
1 Answers

I think the only way is to read files at build time using fs and process.cwd() inside getStaticProps.
Something like this :

import { promises as fs } from 'fs'
import path from 'path'

const Test= ({ urls }) => {
    return (
        <ul>
            {
                urls.map(el => <li key={el}>{el}</li>)
            }
        </ul>
    )
}

export async function getStaticProps() {
    const postsDirectory = path.join(process.cwd(), '/pages')
    const filenames = await fs.readdir(postsDirectory)
    return {
        props: {
            urls: filenames,
        },
    }
}

export default Test

You can also store page infos (such paths and names) in a database and query the database instead.

Related