title: How to generate a menu based on the files in the pages directory in Next.js
body: <p>I am trying to create a menu component that reads the contents of the pages folder at build time. However I haven't had any success. Here is what I have tried:</p>
  <pre><code>import path from &quot;path&quot;;
  import * as ChangeCase from &quot;change-case&quot;;
  
  export default class Nav extends React.Component {
      render() {
          return (
              &lt;nav&gt;
                  {this.props.pages.map((page) =&gt; (
                      &lt;a href={page.link}&gt;{page.name}&lt;/a&gt;
                  ))}
              &lt;/nav&gt;
          );
      }
  
      async getStaticProps() {
          let files = fs.readdirSync(&quot;../pages&quot;);
          files = files.filter((file) =&gt; {
              if (file == &quot;_app.js&quot;) return false;
              const stat = fs.lstatSync(file);
              return stat.isFile();
          });
  
          const pages = files.map((file) =&gt; {
              if (file == &quot;index.js&quot;) {
                  const name = &quot;home&quot;;
                  const link = &quot;/&quot;;
              } else {
                  const link = path.parse(file).name;
                  const name = ChangeCase.camelCase(link);
              }
              console.log(link, name);
              return {
                  name: name,
                  link: link,
              };
          });
  
          return {
              props: {
                  pages: pages,
              },
          };
      }
  }
  </code></pre>
  <p>This does not work, the component does not receive the pages prop. I have tried switching to a functional component, returning a promise from <code>getStaticProps()</code>, switching to <code>getServerSideProps()</code>, and including the directory reading code into the render method.</p>
  <p>The first two don't work because <code>getStaticProps()</code> and <code>getServerSideProps()</code> never get called unless the component is a page, and including the code in the render method fails because fs is not defined or importable since the code might run on the front end which wouldn't have fs access.</p>
  <p>I've also tried adding the code to a <code>getStaticProps()</code> function inside <code>_app.js</code>, with the hopes of pushing the pages to the component via context, but it seems <code>getStaticProps()</code> doesn't get called there either.</p>
  <p>I could run the code in the getStaticProps function of the pages that include the menu, but I would have to repeat that for every page. Even if I extract the logic into a module that gets called from the getStaticProps, so something like:</p>
  <pre><code>// ...
  
  export async function getStaticProps() {
      return {
          props: {
              pages: MenuMaker.getPages(),
              // ...
          }
      }
  }
  </code></pre>
  <p>and then pass the pages to the navigation component inside the page via the Layout component:</p>
  <pre><code>export default function Page(props) {
      return (
          &lt;Layout pages={props.pages}&gt;&lt;/Layout&gt;
      )
  }
  </code></pre>
  <p>then that's still a lot of boilerplate to add to each page on the site.</p>
  <p>Surely there is a better way... It can't be that there is no way to add static data to the global state at build time, can it? How do I generate a dynamic menu at build time?</p>