Closed timneutkens closed 4 years ago
export async function getStaticProps(context) { return { // Unlike `getInitialProps` the props are returned under a props key // The reasoning behind this is that there's potentially more options // that will be introduced in the future. // For example to allow you to further control behavior per-page. props: {} }; }
I'm interested in seeing what circumstance we would need to return additional data other than what can be contained within props
. I found the in-line explanation "to further control behavior per-page" a bit vague.
Looks very interesting! Would his be a replacement for getInitialProps
or along side? For eg, for our use case, the data fetching API is a public service. So on client side navigation, we expect the client to directly call the API layer, whereas on SSR the server calls it. Going forward, would this use case continue to be solved by the prior method?
I'm interested in seeing what circumstance we would need to return additional data other than what can be contained within
props
. I found the in-line explanation "to further control behavior per-page" a bit vague.
It's more so about future proofing the method so that it allows us to extend it later on if needed.
Looks very interesting! Would his be a replacement for
getInitialProps
or along side? For eg, for our use case, the data fetching API is a public service. So on client side navigation, we expect the client to directly call the API layer, whereas on SSR the server calls it. Going forward, would this use case continue to be solved by the prior method?
In general that behavior has some downsides, for example waterfall fetches that could be slow from certain areas around the world. The getServerProps
approach allows for caching the response more efficiently.
This looks really interesting! Cool idea!
I have concerns about deployment though...
Let's imagine I'm hosting on Now.
For the first deployment, it's obvious that the whole applications gets built on deployment.
Then, I change some content in CMS and am looking to trigger rebuild of SSG pages only, but the application code has not changed.
Immediately alarm goes off, that in this case if I trigger the build, there are two possible solutions:
1) Nothing gets rebuilt, as everything is cached - no code has changed and blabla.
2) I --force
it, and now "everything" gets rebuilt, but I only required the SSG pages to be rebuilt.
These are just hypotheses, as that depends on build systems themselves - how aware are they of Next
This would probably affect any other hosting solution.
Next itself has a .next/cache
... how would this play around that?
@joltmode that's basically the case for every static site generator currently. .next/cache
is preserved between deployments on Now and reused. Keep in mind that you're currently probably using getInitialProps for this case with caching (potentially https://zeit.co/blog/serverless-pre-rendering), which dynamically renders in a serverless function and then caches on our CDN, this behavior is still totally fine and will continue to work if you use getServerProps
.
Really awesome, would fit nicely into how we are using Next for customer projects, and would remove some boilerplate code we copy around.
One thing to consider is the naming of getStaticProps and getServerProps, if they return a { props } and potential other options in the future, would the *Props not be confusing? Maybe getStaticConfiguration, getStaticSetup, getStaticOptions would be more generic?
@kibs the return values would always relate to how the props are handled. So the naming is fine imo.
This is simply awesome! This is solving every use case and need I've had recently or could think of while developing both private and professional web apps. You just prevented me from starting my own hybrid site generator, thanks!
I can also relate to the new methods being better than the previous getInitialProps()
and exportPathMap()
, which sounded a bit confusing to me at first when I started using Next.js and digged into SSR / SSG. The per-page approach makes more sense to me too.
Can't wait to try this out!
Just a side note : in the last example I think
getServerProps()
is missing acontext
param.
Just a side note : in the last example I think getServerProps() is missing a context param.
Fixed!
This sounds great! I just wonder from a TypeScript user perspective if having getStaticProps
, getStaticPaths
and getServerProps
as static methods on the page component (like getInitialProps
at the moment) would be easier to type/use correctly.
const Page: NextPage<Props> = (props) => ...
// Explicit types needed here
export const getStaticPaths: NextGetStaticPaths<Params> = () => ...
export const getStaticProps: NextGetStaticProps<Props, Params> = (context) => ...
export const getServerProps: NextGetServerProps<Props> = (context) => ...
export default Page
// vs.
const Page: NextPage<Props, Params> = (props) => ...
// Static method types come from NextPage<Props, Params>
Page.getStaticPaths = () => ...
Page.getStaticProps = (context) => ...
Page.getServerProps = (context) => ..
export default Page
@herrstucki the problem with that approach is that it becomes significantly harder to tree shake (read: close to impossible). Which would mean unnecessary code would be shipped to the browser.
@timneutkens good point … but would then a separate file not make even more sense? Or is something like this reliably tree-shakable?
// This should all be removed in client-side code …
import {fetchQuery, queryTag} from 'big-data-fetching-lib';
const query = queryTag`...`
export const getStaticProps = async () => ({ props: await fetchQuery(query) })
// Only this should be included client-side
export default (props) => ...
@herrstucki we can reliably tree shake that, but we're also still discussing having a separate file. Personally I prefer the single file approach though.
Looks very interesting! Would his be a replacement for
getInitialProps
or along side? For eg, for our use case, the data fetching API is a public service. So on client side navigation, we expect the client to directly call the API layer, whereas on SSR the server calls it. Going forward, would this use case continue to be solved by the prior method?In general that behavior has some downsides, for example waterfall fetches that could be slow from certain areas around the world. The
getServerProps
approach allows for caching the response more efficiently.
Sure, but I'm talking about avoiding the RTT to the react server at all. Consider the case where the SSR output from the server is cached at CDN / cache server proxy. Couple that with data fetching for client navigation directly calling a different API layer (common to web / apps / all clients), means that the Next.js server layer doesn't have to be scaled up as much in a high traffic scenario.
I understand your point of waterfall fetches, but giving consumers the ability to treat the Next server as a SSR layer vs a data source would allow for much better scaling setups.
Looks very interesting! Would his be a replacement for
getInitialProps
or along side? For eg, for our use case, the data fetching API is a public service. So on client side navigation, we expect the client to directly call the API layer, whereas on SSR the server calls it. Going forward, would this use case continue to be solved by the prior method?In general that behavior has some downsides, for example waterfall fetches that could be slow from certain areas around the world. The
getServerProps
approach allows for caching the response more efficiently.Sure, but I'm talking about avoiding the RTT to the react server at all. Consider the case where the SSR output from the server is cached at CDN / cache server proxy. Couple that with data fetching for client navigation directly calling a different API layer (common to web / apps / all clients), means that the Next.js server layer doesn't have to be scaled up as much in a high traffic scenario.
I understand your point of waterfall fetches, but giving consumers the ability to treat the Next server as a SSR layer vs a data source would allow for much better scaling setups.
I think you're misunderstanding that this new behavior means you can actually cache the full results on a CDN given the CDN supports dynamic responses. This was previously not reliably possible with getInitialProps.
@timneutkens I played around with canary, trying to port some babel-plugin-preval
code to getStaticProps
. I am ran into an issue with fs
.
I am trying to read the .md files of my ./pages/blog/
directory and loop through them so I can make a blog index page with all my posts
import React from 'react';
import Link from 'next/link';
import fs from 'fs-extra';
const Index = ({ posts }) => (
<div>
Hello World. <Thing msg="hello" />
<Link href="/thing">
<a>About</a>
</Link>
{posts.map(p => (
<div key={p.title}>{p.title}</div>
))}
</div>
);
Index.getStaticProps = async () => {
const items = await fs.readdir('./pages/blog');
items.forEach(path => /* .... do some stuff ... */ )
return { props: { posts: items } };
};
export default Index;
This code leads to this error:
Module not found: Can't resolve 'fs' in '/Users/jared/Downloads/nextjs-typescript-template/node_modules/fs-extra/lib'
IIRC from Razzle, this error has to do with webpack's filesystem stubs (or lack thereof). I think I once fixed this with Razzle by adding this to the webpack config.
node: {
fs: "empty";
}
I tried this next.config.js, but it just makes the error go away. It appears though that fs
/fs-extra
doesn't actually work, or it does and perhaps paths don't (unclear to me). Any thoughts on that?
My other question, more generally, is what you imagine best practices will be for using import vs. require in getStaticProps
. If I'm not mistaken, my above snippet will attempt to import fs-extra
in React isomorphically??. Would it thus be better to change the import to an inline require like this?
Index.getStaticProps = async () => {
const fs = require('fs-extra'); // only require when needed at SSG
const props = await fs.readdir('./pages/blog');
return { props: { posts } };
};
I think you're misunderstanding that this new behavior means you can actually cache the full results on a CDN given the CDN supports dynamic responses. This was previously not reliably possible with getInitialProps.
Ah, I think I get what you mean. Would that mean that getServerProps
on the first SSR generation would create a unique endpoint, in a content addressable hash maybe in the URL maybe that we can then cache on the CDN? The only downside of this would be that said cache would not be shareable between non Next apps (android / ios) and Next apps. Additionally, with an external data source, the cache control directives are upstream, but here since Next would assume responsibility of serving up the data, we need APIs or props to specify those for the generated data endpoints.
@jaredpalmer I assume https://github.com/zeit/next.js/issues/9524#issuecomment-558628066 (including my concern about reliable tree-shakeability) would be resolved by having a separate file that would be compiled completely separately from client bundle code? E.g.
pages/
foo.js
foo.data.js (<- exports getStaticProps etc.)
or:
pages/
foo.js
pages-data/
foo.js (<- exports getStaticProps etc.)
@jaredpalmer tree shaking wasn't implemented yet on canary.
As always, thank you for everything y'all do. Next.js has been an absolute joy to work with, and as I've said before, just about every feature release lets us reduce the size of the codebases I manage. It's amazing.
It's hard to be critical of this RFC since, as written, it is immediately useful for a LOT of applications. I do, however, want to address one line that I'm not sure I agree with:
"
getStaticPaths
replaces the need for having aexportPathMap
and works per-page."
In some applications, it is either impractical or impossible to know the routes at build time. A few examples would be:
Routes for pages like this will probably be in the form /entity-name/entity-id
and Next's dynamic routes work really really well since you can do things like router.push('/customers/[customerId]', '/customers/baer')
. There is still a catch. If you plan to serve these files statically with something like Serve, Netlify, NGINX, etc, you'll need to generate a set of redirects so that users won't get a 404 on page-refresh and, to do that, you still need exportPathMap
.
The following is copied, almost as-is, from a codebase I work on regularly:
const buildServeConfig = redirects => {
const config = {
public: `dist`,
trailingSlash: true,
rewrites: redirects
};
const outputPath = `${__dirname}/serve.json`;
fs.writeFile(outputPath, JSON.stringify(config, null, 2), err => {
if (err) {
throw err;
}
// eslint-disable-next-line no-console
console.log(`Generated: ${outputPath}`);
});
};
...
exportPathMap: function(defaultPathMap, { dev, outDir }) {
const redirects = Object.entries(defaultPathMap)
// No need to create a redirect rule for `/dirname/` or `/dirname/index.html`
.filter(([url]) => url !== `/` && url !== `/index`)
.map(([url, { page }]) => ({
// Replaces /[customerId] with /:customerId
source: url.replace(/]/g, ``).replace(/\[/g, `:`),
destination: `${page}/index.html`
}));
// By default, the routes are sorted such that a route like `/order/:orderId`
// comes before `/order/new`. Since the `:orderId` portion of `/order/:orderId`
// is a wildcard, the route `/order/new` will be a match and consider `new`
// as a value for `:orderId`. To get past this, we sort the redirects by the
// number of parameters in ascending order.
const sortedRedirects = [...redirects].sort(
(currentRedirect, nextRedirect) =>
currentRedirect.source.split(`:`).length >
nextRedirect.source.split(`:`).length
);
buildServeConfig(sortedRedirects);
return defaultPathMap;
}
I understand that this RFC does not deprecate or remove any APIs and I also recognize that it is possible to build these redirects by traversing the build directory so even if it were deprecated, I've got a nice ecape hatch. But, it doesn't quite "remove the need for getStaticPaths
."
Again, thank you for your thoughtfulness in how you run this project
Are
getStaticProps
/getStaticPaths
andgetServerProps
mutually exclusive? i.e. would it be possible to have a part prerendered and a part dynamic at the same time?
Yeah they are as one is static generation and one is server-side rendering.
This fixes one of the big things I miss from Gatsby before we migrated to Next:
We have a monolithic (100s of kbs) JSON file that we pull data from to render our pages that never changes. In Gatsby we loaded the JSON file into the GraphQL schema and queried against that, only grabbing the data that we needed to render a given page. With Next, the easiest/cleanest way we found to do this is import monolith from './monolith.json'
, which requires the user download the entire JSON file.
This RFC 100% addresses this use case and brings Next one step closer to being on-par with Gatsby in the areas Gatsby shines (obviously, Gatsby can't do runtime SSR, so I'm only talking about static buildtime renders)
@timneutkens, thank you for the RFC!
I have a use case for Next.js that I recently discussed with @rauchg.
Next.js delivers very smooth DX and some reasonable defaults. So, I'm interested in using Next.js for a client-side only rendered application, a Smart TV app.
Smart TV apps are almost classic web apps that are run by TV’s browser engine:
The thing is that the bundle is statically hosted by the TV device itself and not loaded from the server. Thus, no SSR option is possible (Node.js isn’t exposed to developers for these purposes). But the app itself is dynamic (say, Netflix).
So, we need to run an SPA that is hosted by a static web server.
As I understand opting-out of getServerProps
(or getInitialProps
) completely will help to avoid SSR. But what happens with dynamic rendering on the client? And what about routing in this case? According to this RFC the problem hasn’t been addressed yet. @timneutkens, could you, please, suggest the best way to enable client-side only rendering in Next.js? And whether it fits Next.js in the first place? Thanks!
P.S. I can create an issue for this use case if you think it's better to discuss it separately.
@grushetsky can you create a different issue. This is a completely different question from what is being discussed in the RFC 👍
@timneutkens The promise of this RFC is one of the things that got me super excited about Next! Just to clarify though, getInitialProps
would still exist too, right?
Correct @outdooricon -- getInitialProps
will remain around for the foreseeable future.
Per the RFC:
This RFC exclusively discusses API additions. All new functionality is completely backwards compatible and can be incrementally adopted. This RFC introduces no deprecations.
Great RFC, super excited for this!
I've been thinking about the getServerProps
in relation to a specific use case, putting the results in a cache. Since this gets turned into a API-endpoint and the result delivered to the component as props, is there a prescribed way of putting the result into an external cache like Redux, GraphQL-caches etc, etc client side?
If I understand getInitialProps
correctly, since it's static and async, Next has the opportunity to wait for it to complete before ever rendering the component a first time. This lets us put things into an external cache there. This won't be the case with getServerProps
since it runs on the server, and putting things in a cache in the component lifecycle seems to mean we have to have a render where the data is not available in the cache yet, even if it is available in props?
This might be intentional of course and I might be missing an approach, but I thought I'd ask if it's something that's been considered?
Edit: I guess this also applies to getStaticProps
. 😄
Maybe I've missed it somewhere, but how do we handle situations when content is cached, but it is updated in db or new blog post is created? There is need to do new build automatically? I guess so.
First of all! Great proposal, it's a massive improvement over exportPathMaps
on most people's use case. It's really appreciated. With that said, I'm struggling to understand how would we will be able to make it work with route internationalisation.
Is there any suggestions on how to handle i18n prefixed routes? My specific use case requires to build a few thousands on pages with different country-lang prefixes and urls.
/nl/brillen
/gb/glasses
/es/gafas
...
It seems that getStaticPaths
will be really helpful when the prefix for the url is well known, as in your example (using /blog/[id].js
). But how do you think a getStaticPaths
implementation will look if it needs to generate paths at root level, with both a dynamic prefix (country-lang) and a dynamic path?
@reaktivo pages/[lang]/blog/[id].js
-> in getStaticPaths
provide all urls to statically render.
@timneutkens Any idea when this will be available / testable?
In general we don't give out ETAs because we extensively test features against production apps to make sure the solution is right.
This improvements will totally make me deprecate my "not that maintained" phenomic project (react ssg that nobody uses except me). Awesome to see Next.js adding this missings parts!
I would like to clarify a doubt. Considering the use of a CMS like wordpress. As I understand it, with the getStaticPaths method I would fetch all posts and pass a list like:
export async function getStaticPaths () {
return [
// This renders / blog / hello-world to HTML at build time
{params: {slug: "hello-world"}}
];
}
The slug of each post would be used in the getStaticProps method to fetch the content. This would happen in npm build. My question is about new posts that will be added after the build. Would getStaticProps method be used to fetch this new post by slug? Will this new post have a .html file like the one in the previous build? I love to work with next and in several projects I have this would be very good.
Nothing directly related, but the support is unable to give me an answer that matches my question.
What you suggest here could be the solution, but in the meantime, I'm unable to make nextJS to build a JAMSTACK based on webhooks changes.
if I had getInitialProps I'm going to be server-rendered. If I don't, I'm just CDNized, but without pre-rendering isn't? And the page will be without content as long as XHR haven't returned (bye-bye SEO)
Do you have any running example with now of Jamstack with nextJS and we could do on netlify.
Thanks, Andréas
Hey @ScreamZ - this change is, I think, what enables a fully static site to be built with nextjs. We have been able to compile out a nextjs site to static using next export
for a long time, but it would still fetch data on client-side route transitions using getInitialProps
. With the ability to use getStaticProps
, you can run client-side transitions without any additional data being fetched -- all fetched data in getStaticProps
is fetched once, at build time, and not updated on your live site unless you rebuild again. This is the classic architecture of data-driven static sites, link your data source to your host via webhook and when the data source changes, you tell the host to rebuild your site.
There are plenty of existing examples of fully static nextjs websites, and its trivial to run a nextjs site on netlify. My company's website is currently running on nextjs, and hosted by netlify, hopefully this serves as a good example.
It's very much worth noting that zeit's hosting service is also something worth being strongly considered. The pricing is quite similar, and their integration with nextjs sites is second to none - you literally don't even need to configure anything at all, you just link github and zeit's hosting will recognize that you're running nextjs and automatically configure and deploy everything.
This is not an advertisement by any means, I do not work for zeit, just a genuine endorsement. You can absolutely make it work with netlify, and I have personally for several sites as proof. But you will need to understand thoroughly how nextjs works, and you will need to make sure everything is configured correctly to get it running smoothly on netlify. If you're looking for the simplest, most foolproof hosting for a nextjs site, I would give zeit's hosting a try.
@jescalan Thank you for this great sharing 🙏🏻
I've no issue using NextJS with netlify, because you can use Publish directory
to specify the out
folder. But on zeit Now, there is no way to say, please don't use SSR but go full on static with next export
.
@ScreamZ this is sort of true, but it depends on how exactly you define a "full static" site. If you use getStaticProps
for all your pages with zeit's hosting service, what you will get is effectively equal to a static site, even if it doesn't run next export
, since all pages with getStaticProps
are built only when the site is deployed, and are served directly from the CDN after that.
The main difference is that as far as I know there isn't a way to force all pages to be static on zeit's hosting (edit: zeit recently changed it so that any site with a config that contains exportPathMap
will run a fully static site, so this is no longer true). Pages with getStaticProps
behave exactly the same as pages generated by next export
-- a single static copy of the page is served directly from the CDN on every hit. But you could also run some pages with getServerProps
or getInitialProps
and they would behave as server rendered pages. Personally I see this as a benefit -- if there's a need for a SSR route you can simply use a different data fetching method and that single route is now SSR, while all your other routes can remain static.
@jescalan Thanks,
So just need to wait to have this being implemented, in the meantime gonna use netlify for static
Is there a story around SSG configuration? Specifically we would like to use shared build artifacts but run next export
with different configurations for QA/prod. These config values would only be read in getStaticProps
. Would this use the serverRuntimeConfig
or publicRuntimeConfig
or process.env
directly?
@ScreamZ @jescalan I've landed zero-config next export
support on Now today together with @Timer (he deserves all the credits). You can do:
"build": "next build && next export"
And it'll work automatically.
Let me know how it goes 🙏
Yeah, I was the guy that asked on support and they told me this has been implemented just yet 😅 As far as I can see, you'll need to define an export map in config?
@ScreamZ no you can just add next build && next export
as shown above and it'll work.
@timneutkens If I replace getInitialProps
with getServerProps
, do I still need to add target: 'serverless'
to the config file to enable Server Pre Rendering
? Thanks.
How can we try these?
How can we try these?
I guess all these methods currently need unstable_
prefix to get recognized.
e.g unstable_getStaticProps
@timneutkens
@ScreamZ @jescalan I've landed zero-config
next export
support on Now today together with @Timer (he deserves all the credits). You can do:"build": "next build && next export"
And it'll work automatically.
Let me know how it goes 🙏
My build script is doing a bit more things but it looks like it works like a charm:
"build": "graphql codegen && next build && npm run export",
Besides, it's great! It was exactly what I was looking for 😅 (Goodbye GatsbyJS, my favorite framework is now strong as you!)
Thanks a lot for such reactivity.
I also upgraded to 9.1.6
and I surprisely saw that
I thought that thread was an RFC, it looks like it's already opened to us ahah, isn't ? However, Typescript types are not enabled in 9.1.6.
Damn, I'm so hyped for that now! 🤣
Last questions:
getInitialProps
will be deprecated in the future? Or is it still relevant in some cases? An example?next export
can also be deprecated in favor of pages with getStaticProps
and next build
only?Thanks for that great tool 🙏🏻
If I get it, getInitialProps will be deprecated in the future? Or is it still relevant in some cases? An example?
As said in the initial RFC:
This RFC exclusively discusses API additions. All new functionality is completely backwards compatible and can be incrementally adopted. This RFC introduces no deprecations.
I thought that thread was an RFC, it looks like it's already opened to us ahah, isn't ?
It's not, we're trying it out on ZEIT applications and some of the visibility surfacing has already landed (for example the pages tree you saw).
next export can also be deprecated in favor of pages with getStaticProps and next build only?
Correct, in general you'll end up just not using next export
. It'll be kept around for backwards compat reason but in general you'll want to create a hybrid app as it gives you all the benefits of export with support for other features like API routes and opting into server-side rendering for some pages.
How can we try these?
I guess all these methods currently need
unstable_
prefix to get recognized.e.g
unstable_getStaticProps
Highly recommend not using it yet, it's experimental and can break between releases.
Summary
Allow Next.js to become fully hybrid by providing methods to do both static generation and server-side rendering on a per-page basis.
getStaticProps
- Opt-in to static generation (SSG) atnext build
time.getServerSideProps
- Opt-in to server-side rendering (SSR) which renders on-demand.getStaticPaths
- Return list of parameters for dynamic routes to do static generation (SSG)This RFC exclusively discusses API additions. All new functionality is completely backwards compatible and can be incrementally adopted. This RFC introduces no deprecations.
Background
When building websites or web applications you generally have to choose between 2 strategies: Static generation (SSG) or server-side rendering (SSR).
Next.js instead lets you build hybrid applications that allow you to choose per-page which strategy is used. Starting with Next.js 9, pages without
getInitialProps
get statically optimized and output as.html
files uponnext build
.However, you might want to do data fetching while generating static pages for your specific use case.
For example, to statically generate marketing pages from a CMS or a blog section of the site.
Using
getInitialProps
would opt you into SSR in that case.Next.js currently has a
next export
command, that makes the application fully SSG, losing the hybrid nature of Next.js.If you use
next export
withgetInitialProps
there is another problem that surfaces.getInitialProps
is called at build time (which is great), but then when you usenext/link
to move between pagesgetInitialProps
is called client-side, instead of using thenext export
result.This also means the data source (CMS / API endpoint) is called directly on client-side transitions, if your data source is down, client-side transitions break while moving between pages.
We've collaborated with heavy users of SSG and
next export
in Next.js like HashiCorp (thanks @jescalan) and extensively investigated the right constraints for introducing two new data fetching methods:getStaticProps
andgetServerSideProps
. But also a way to provide parameters to statically generate static pages for dynamic routes:getStaticPaths
(replacement forexportPathMap
that is per-page).These new methods have many advantages over the
getInitialProps
model as there is a clear distinction between what will become SSG vs SSR.getStaticProps
marks the page to be statically generated at build time (when runningnext build
)getStaticPaths
allows for returning a list of parameters to generate at build time for dynamic routesgetServerSideProps
marks the page to be server-side rendered on every request and is the most similar to the currentgetInitialProps
behavior when using a server.Separating these methods also allows us to provide the correct context object that can be typed using TypeScript. When you opt for a specific rendering strategy you get the correct values, currently with
getInitialProps
you have to guess what is available on SSG vs SSR when using TypeScript.Furthermore, by making these methods explicit, it'll allow us to document the different trade-offs more clearly.
Implementation
Note that all these methods are top-level on the page component file and can't be nested, similar to
getInitialProps
.getStaticProps
Using
getStaticProps
means the page will be rendered statically at build time (SSG).This new method will allow you to do data fetching for a page that will be statically generated into a
.html
file atnext build
time.Next.js will also automatically generate a JSON file that holds the result of
getStaticProps
atnext build
time. This is being used for client-side routing.When client-side routing through
next/link
ornext/router
, Next.js will fetch this JSON file to get the props needed to render the page client-side.Properties are returned under a
props
key so that other options can be introduced in the future.The
context
will contain:params
- The parameters when on a dynamic route.getStaticPaths
This is an extension on
getStaticProps
usage for dynamic routes.getStaticPaths
replaces the need for having aexportPathMap
and works per-page.Since you might want to statically generate a list of urls that have a dynamic parameter, like in the example below a
slug
. Next.js will provide agetStaticPaths
method that allows for returning a list of urls. Since it's aasync
method you can also fetch that list from a data source like your CMS.Fallback
In many cases you might not want to pre-render every possible route in your application at build-time (for example if you have millions of products). For this reason Next.js will automatically generate a
fallback
page that is a render of the page without data (so that a loading state can be shown) for when the page hasn’t been generated yet.The exact behavior of serving will be:
In case you want paths that weren’t generated at build time to result in a 404 that is also possible by returning
fallback: false
fromgetStaticPaths
getServerSideProps
When using
getServerSideProps
, the page is not statically generated (SSG) and instead renders on-demand on every request to the server (SSR).Next.js will also automatically expose an API endpoint that returns the result of calling
getServerSideProps
. This is being used for client-side routing.When client-side routing through
next/link
ornext/router
, Next.js will fetch this exposed API endpoint to get the JSON data that is turned into the props needed to render the page client-side.This method is the most similar to the current
getInitialProps
, with the main difference beinggetServerSideProps
is always executed server-side instead of in the browser. Either on server-side rendering or the API fetch when client-side routing.Similarly to
getStaticProps
the properties are returned under aprops
key.The
context
will contain:params
- The parameters on a dynamic routereq
- The HTTP request objectres
- The HTTP response objectquery
- The query string (not entirely sure about this one, but probably needed)Authored by @timneutkens, @Timer, @ijjk, @lfades. Collaborated with @rauchg, @jescalan and others 🚀