# Passing Information to getStaticProps
While `getStaticProps` doesn't directly accept arguments in the way a regular function would, there are a couple of ways to pass information to it:
- Using Dynamic Routes (opens new window): If you're using dynamic routes, you can access route parameters in getStaticProps.
- Using contextobject:getStaticPropsreceives acontextobject which can contain additional information.
# Using Dynamic Routes
If you have a dynamic route, like pages/posts/[id].js, you can access the id parameter in getStaticProps.
Consider the following tree structure:
➜  nextra-casiano-rodriguez-leon-alu0100291865 git:(guide) ✗ tree -I 'node_modules|api|advanced|auth|components|public|src|data|protected|*.mdx|*.jsx|_meta*' -P 'pages|posts|\[id\].js' --matchdirs
.
├── pages
│   ├── posts
│   │   └── [id].js
│   └── user
└── posts
    ├── 2024-12-08-leccion.md
    └── 2024-12-09-leccion.md
2
3
4
5
6
7
8
9
Then you can access the id parameter in getStaticProps like this:
filename="pages/posts/[id].js"
import { promises as fs } from 'fs'
import path from 'path'
import { useRouter } from 'next/router'
//import { NotFoundPage } from 'nextra-theme-docs'
import { remark } from 'remark'
import html from 'remark-html'
import styles from '@/styles/Home.module.css'
import markdownStyles from '@/styles/Markdown.module.css'
export default function Post({ filename, contentHtml }) {
  const router = useRouter()
  if (router.isFallback) {
    return <div>Loading...</div>
  }
  if (!contentHtml) {
    return (<div className={styles.content}>
              <h1 className={styles.title}>404. Page not found!</h1>
            </div>)
  }
  return  (
    <div className={styles.container}>
      <h1 className={styles.title}>{filename}</h1>
        <article key={filename} className={styles.article}>
          <div 
            className={`${styles.content} ${markdownStyles.markdown}`}
            dangerouslySetInnerHTML={{ __html: contentHtml }} 
          />
        </article>
    </div>
  )
}
export async function getStaticProps({ params }) {
  const { id } = params
  const postsDirectory = path.join(process.cwd(), 'posts')
  const filePath = path.join(postsDirectory, `${id}.md`)
  try {
    const postContent = await fs.readFile(filePath, 'utf8')
    const processedContent = await remark()
        .use(html)
        .process(postContent)
    
    const contentHtml = processedContent.toString()
    return {
      props: {
        filename: id,
        contentHtml,
      },
    }
  } catch (error) {
    // If the file is not found, return null for contentHtml
    if (error.code === 'ENOENT') {
      return {
        props: {
          filename: id,
          contentHtml: null,
        },
      }
    }
    throw error
  }
}
export async function getStaticPaths() {
  const postsDirectory = path.join(process.cwd(), 'posts')
  const filenames = await fs.readdir(postsDirectory)
  const paths = filenames.map((filename) => ({
    params: { id: filename.replace(/\.md$/, '') },
  }))
  return { paths, fallback: true }
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
In this example, getStaticProps receives the id from the URL parameters and uses it to read the corresponding file.
Notice how we're handling non-existent posts.
- In getStaticPaths, we've setfallback: true(opens new window). This allows Next.js to generate pages for paths that weren't pre-rendered at build time .
- In getStaticProps, if the file is not found, we returnnullforpostContentinstead of throwing an error.
- In the Postcomponent, we've added checks for the fallback state and for whenpostContentis null:
- We use the useRouterhook to check if the page is in a fallback state.
- When a request comes in for a page that wasn't pre-rendered, Next.js starts generating the HTML and JSON for that page.
- During this generation process, router.isFallbackistrue.
- Once the page generation is complete, Next.js serves the newly generated page, and for subsequent requests, router.isFallbackwill befalse
- Relationship of router.isFallbackwithfallbackingetStaticPaths:- If fallback: false,router.isFallbackwill always befalsebecause any paths not returned bygetStaticPathswill result in a 404 page.
- If fallback: trueorfallback: 'blocking',router.isFallbackcan betruefor paths not pre-rendered at build time .
 
- If 
- Remember, router.isFallbackis only relevant for pages with dynamic routes that usegetStaticPropsandgetStaticPaths. It's not applicable to pages usinggetServerSidePropsor client-side data fetching.
- If postContentisnull(meaning the post wasn't found), we render a404. Page not found!message.
Now, when you visit a post that doesn't exist:
- If the post hasn't been generated yet, you'll briefly see a Loading...message while Next.js attempts to generate the page.
- If the post truly doesn't exist, you'll see a 404. Page not found!message.
# The role of the function getStaticPaths
 The function getStaticPaths plays a crucial role in Next.js (opens new window) is used to specify which dynamic routes should be pre-rendered at build time.
Here's an explanation of its purpose and functionality:
- Specifying Dynamic Routes: - getStaticPathsis used to define which paths will be pre-rendered for pages that use dynamic routes. In the example above, it's determining which post IDs should be pre-rendered at build time.
- Static Generation: When you export - getStaticPathsfrom a page that uses dynamic routes, Next.js will statically pre-render all the paths specified by- getStaticPaths. This means that these pages are generated at build time, resulting in faster page loads and better SEO.
- Defining Paths: The function returns an object with a - pathskey, which is an array of objects. Each object in this array represents a route that should be pre-rendered . In our example, it's creating a path for each markdown file in the- postsdirectory.
- Fallback Behavior (opens new window): - getStaticPathsalso allows you to control the fallback behavior for paths that aren't pre-rendered. In our example,- fallback: false(opens new window) means that any paths not returned by- getStaticPathswill result in a 404 page .
- Build-Time Execution: - getStaticPathsruns at build time in production. It's not called during runtime in production, which is important for performance .
Here's a breakdown of what our getStaticPaths function is doing:
export async function getStaticPaths() {
  const postsDirectory = path.join(process.cwd(), 'posts')
  const filenames = await fs.readdir(postsDirectory)
  const paths = filenames.map((filename) => ({
    params: { id: filename.replace(/\.md$/, '') },
  }))
  return { paths, fallback: false }
}
2
3
4
5
6
7
8
9
10
- It reads the postsdirectory.
- For each file in the directory, it creates a paramsobject with anidthat corresponds to the filename (without the.mdextension).
- It returns these paths, telling Next.js to pre-render a page for each of these ids.
This function works in tandem with getStaticProps. While getStaticPaths defines which paths to pre-render, getStaticProps is then called for each of these paths to fetch the data needed to render the page .
By using getStaticPaths, you're able to create static pages for dynamic routes, combining the benefits of dynamic content with the performance and SEO advantages of static generation.
# Using the context object
 The context object passed to getStaticProps
Contains several properties (opens new window) that you can use :
- params: If you're using dynamic routes (opens new window),- paramscontains the route parameters.
- draftMode:- trueif the page is in the Draft Mode (opens new window) and- falseotherwise. Is useful when your pages fetch data from a headless CMS (opens new window) and you’d want Next.js to render these pages at request time instead of build time and fetch the draft content instead of the published content. You’d want Next.js to bypass Static Generation only for this specific case.
- preview: (Deprecated for draftMode) A boolean indicating if the page is in preview mode (opens new window).
- previewData: (Deprecated for draftMode) The preview data set by- setPreviewData.
- locale: The active locale, if you're using internationalization.
- locales: All supported locales, if you're using internationalization.
- defaultLocale: The default locale, if you're using internationalization.
Here's an example using some of these properties:
import { promises as fs } from 'fs'
import path from 'path'
export default function ContextExample({ files }) {
  return (
    <div>
      <h1>File Reader Example</h1>
      <ul>
        {files.map((file) => (
          <li key={file.filename}>
            <h3>{file.filename}</h3>
            <pre>{file.content}</pre>
          </li>
        ))}
      </ul>
    </div>
  )
}
export async function getStaticProps(context) {
  const { preview = false } = context
  const postsDirectory = path.join(process.cwd(), 'posts')
  const filenames = await fs.readdir(postsDirectory)
  const files = await Promise.all(
    filenames.map(async (filename) => {
      const filePath = path.join(postsDirectory, filename)
      const content = await fs.readFile(filePath, 'utf8')
      return { filename, content: preview ? content : content.slice(0, 100) + '...' }
    })
  )
  return {
    props: {
      files,
    },
  }
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
In this example, getStaticProps uses the preview flag from the context to determine whether to show full file contents or not.
In this example:
- The getStaticPropsfunction reads the contents of each file in thepostsdirectory.
- It creates an array of files, where each item is an object containing thefilenameandcontentof the file.
- If the page is not in preview mode, we truncate the content to the first 100 characters to avoid sending too much data. You can adjust this as needed.
- The filesarray is passed as a prop to theContextExamplecomponent.
- In the ContextExamplecomponent, we map over thefilesarray and render both the filename and the content of each file.
This approach allows you to access and display the file contents directly in your component. Remember that this data is fetched at build time, so if you need to update the content, you'll need to rebuild your Next.js application.
Also, keep in mind that reading and passing the full content of all files might not be efficient if you have a large number of files or if the files are very large. In such cases, you might want to consider:
- Implementing pagination
- Fetching file contents on-demand (e.g., when a user clicks on a file name)
- Using getServerSidePropsinstead ofgetStaticPropsif you need the latest file contents on each request
# Others
You can get information from environment variables vias process.env or via fetch or reading files from the file system.
# Building the site
See section Building the site.
# References
See the deployment at vercel https://nextra-casiano-rodriguez-leon-alu0100291865.vercel.app/ (opens new window)