- consider incorporating ant-design and making this a portfolio (7/15/20)
- image: https://nextjs.org/static/images/learn/dynamic-routes/page-path-external-data.png
- Goal
- Create Dynamic Pages for blog posts
- Each post is to have path
/posts/<id>
- = name of .md file under root
/posts
directory
- Paths to expect
/posts/ssg-ssr
and/posts/pre-rendering
- Steps to take → an overview
- (1) create a page called ‘[id].js’ under ‘pages/posts’
- Pages wrapped with [] are dynamic in next
- (1) create a page called ‘[id].js’ under ‘pages/posts’
pages/posts/[id].js
- write code that will render a post page
import Layout from '../../components/layout'
export default function Post() {
return <Layout>...</Layout>
}
- export an async function →
getStaticPaths
- in this function, return a list of possible values for
id
- in this function, return a list of possible values for
import Layout from '../../components/layout'
export default function Post() {
return <Layout>...</Layout>
}
export async function getStaticPaths() {
// Return a list of possible value for id
}
- Then, implement
getStaticProps
once more- Fetch data for blog with corresponding
id
getStaticProps
is passedparams
which containsid
- Fetch data for blog with corresponding
import Layout from '../../components/layout'
export default function Post() {
return <Layout>...</Layout>
}
export async function getStaticPaths() {
// Return a list of possible value for id
}
export async function getStaticProps({ params }) {
// Fetch necessary data for the blog post using params.id
}
- Use
[id]
for thehref
and the actual path/posts/ssg-ssr
or/posts/pre-rendering
for theas
prop
<Link href="/posts/[id]" as={`/posts/${id}`}>
<a>{title}</a>
</Link>
- Data Fetching
- Dynamic Routes
- Like getStaticProps, getStaticPaths can fetch data from any data source. In our example, getAllPostIds (which is used by getStaticPaths) may fetch from an external API endpoint:
export async function getAllPostIds() {
// Instead of the file system,
// fetch post data from an external API endpoint
const res = await fetch('..')
const posts = await res.json()
return posts.map(post => {
return {
params: {
id: post.id
}
}
})
}
- In development (npm run dev or yarn dev), getStaticPaths runs on every request.
- In production, getStaticPaths runs at build time.
-
Recall that fallback returned false from getStaticPaths. What does this mean?
- If fallback is false, then any paths not returned by getStaticPaths will result in a 404 page.
- If fallback is true, then the behavior of getStaticProps changes:
-
The paths returned from getStaticPaths will be rendered to HTML at build time.
-
The paths that have not been generated at build time will not result in a 404 page. Instead, Next.js will serve a “fallback” version of the page on the first request to such a path.
-
In the background, Next.js will statically generate the requested path. Subsequent requests to the same path will serve the generated page, just like other pages pre-rendered at build time.
-
Fallback: true documentation
- Dynamic routes can be extended to catch all paths by adding three dots (...) inside the brackets. For example:
- pages/posts/[...id].js matches /posts/a, but also /posts/a/b, /posts/a/b/c and so on.
- If you do this, in getStaticPaths, you must return an array as the value of the id key like so:
return [
{
params: {
// Statically Generates /posts/a/b/c
id: ['a', 'b', 'c']
}
}
//...
]
And params.id will be an array in getStaticProps:
export async function getStaticProps({ params }) {
// params.id will be like ['a', 'b', 'c']
}
- Dynamic Routes documentation for more
- Documentation for the Nextjs useRouter Hook
- Blog Starter using Markdown
- DatoCMS
- TakeShape
- Sanity
- Next supports API Routes
- Allows one to easily create an API endpoint as a Node.js function
- Create a function inside the
pages/api
directory as follows
export default (req, res) => {
//...
}
- These can be deployed as Serverless Functions → Lambdas
- Only use helper functions but never call them directly
- I repeat, never fetch from either of these
- Why?
getStaticProps
andgetStaticPaths
only run server-side- Therefore, it will never be run client-side
- So, it won't be included in the JS bundle for the browser
- For example, direct database queries would never be sent to the browser
- For example, you can create a form on your page and have it send a POST request to your API Route.
- You can then write code to directly save it to your database.
- The API Route code will not be part of your client bundle, so you can safely write server-side code.
export default (req, _res) => {
const email = req.body.email
// then save email to database...etc...
}
-
Static Generation is useful when your pages fetch data from a headless CMS.
-
However, it’s not ideal when you’re writing a draft on your headless CMS and want to preview the draft immediately on your page.
- 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.
-
Next.js has the feature called Preview Mode which solves this problem, and it utilizes API Routes.
-
Preview Mode Documentation
- API Routes can be dynamic just as Next pages can
- Documentation