Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Static Generation / SSG Improvements #9524

Open
timneutkens opened this issue Nov 25, 2019 · 33 comments
Labels
RFC

Comments

@timneutkens
Copy link
Member

@timneutkens timneutkens commented Nov 25, 2019

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.

  • Two new data per-page fetching methods
    • getStaticProps - Opt-in to static generation (SSG) at next build time.
    • getServerProps - Opt-in to server-side rendering (SSR) which renders on-demand.
  • A new method for statically generating (SSG) a set of routes from dynamic sources
    • 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 upon next 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 with getInitialProps there is another problem that surfaces. getInitialProps is called at build time (which is great), but then when you use next/link to move between pages getInitialProps is called client-side, instead of using the next 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 and getServerProps. But also a way to provide parameters to statically generate static pages for dynamic routes: getStaticPaths (replacement for exportPathMap 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 running next build)
  • getStaticPaths allows for returning a list of parameters to generate at build time for dynamic routes
  • getServerProps marks the page to be server-side rendered on every request and is the most similar to the current getInitialProps 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 at next build time.

Next.js will also automatically generate a JSON file that holds the result of getStaticProps at next build time. This is being used for client-side routing.

When client-side routing through next/link or next/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.

// pages/index.js

// getStaticProps is only called server-side
// In theory you could do direct database queries
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: {}
  };
}

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 a exportPathMap 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 a getStaticPaths method that allows for returning a list of urls. Since it's a async method you can also fetch that list from a data source like your CMS.

// pages/blog/[slug].js

// `getStaticProps` gets a `params` object holding the dynamic parameters
// For `/blog/hello-world` it would look like `{ slug: 'hello-world }`
export async function getStaticProps({ params }) {
  return {
    props: {}
  };
}

// `getStaticPaths` allows the user to return a list of parameters to
// render to HTML at build time.
export async function getStaticPaths() {
  return [
    // This renders /blog/hello-world to HTML at build time
    { params: { slug: "hello-world" } }
  ];
}

getServerProps

When using getServerProps, 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 getServerProps. This is being used for client-side routing.

When client-side routing through next/link or next/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 being getServerProps 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 a props key.

// pages/index.js

// getServerProps is only called server-side
// In theory you could do direct database queries
export async function getServerProps(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: {}
  };
}

The context will contain:

  • params - The parameters on a dynamic route
  • req - The HTTP request object
  • res - The HTTP response object
  • query - The query string (not entirely sure about this one, but probably needed)

Authored by @timneutkens, @Timer, @ijjk, @lfades. Collaborated with @rauchg, @jescalan and others 🚀

@timneutkens timneutkens added the RFC label Nov 25, 2019
@timneutkens timneutkens changed the title Static Generation (SSG) Improvements Static Generation / SSG Improvements Nov 25, 2019
@maxchehab

This comment has been minimized.

Copy link

@maxchehab maxchehab commented Nov 26, 2019

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.

@neeharv

This comment has been minimized.

Copy link

@neeharv neeharv commented Nov 26, 2019

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?

@timneutkens

This comment has been minimized.

Copy link
Member Author

@timneutkens timneutkens commented Nov 26, 2019

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.

@timneutkens

This comment has been minimized.

Copy link
Member Author

@timneutkens timneutkens commented Nov 26, 2019

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.

@joltmode

This comment has been minimized.

Copy link

@joltmode joltmode commented Nov 26, 2019

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?

@timneutkens

This comment has been minimized.

Copy link
Member Author

@timneutkens timneutkens commented Nov 26, 2019

@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.

@kibs

This comment has been minimized.

Copy link

@kibs kibs commented Nov 26, 2019

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?

@timneutkens

This comment has been minimized.

Copy link
Member Author

@timneutkens timneutkens commented Nov 26, 2019

@kibs the return values would always relate to how the props are handled. So the naming is fine imo.

@flawyte

This comment has been minimized.

Copy link

@flawyte flawyte commented Nov 26, 2019

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 a context param.

@timneutkens

This comment has been minimized.

Copy link
Member Author

@timneutkens timneutkens commented Nov 26, 2019

Just a side note : in the last example I think getServerProps() is missing a context param.

Fixed!

@herrstucki

This comment has been minimized.

Copy link
Contributor

@herrstucki herrstucki commented Nov 26, 2019

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
@timneutkens

This comment has been minimized.

Copy link
Member Author

@timneutkens timneutkens commented Nov 26, 2019

@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.

@herrstucki

This comment has been minimized.

Copy link
Contributor

@herrstucki herrstucki commented Nov 26, 2019

@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) => ...
@timneutkens

This comment has been minimized.

Copy link
Member Author

@timneutkens timneutkens commented Nov 26, 2019

@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.

@neeharv

This comment has been minimized.

Copy link

@neeharv neeharv commented Nov 26, 2019

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.

@timneutkens

This comment has been minimized.

Copy link
Member Author

@timneutkens timneutkens commented Nov 26, 2019

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.

@jaredpalmer

This comment has been minimized.

Copy link
Contributor

@jaredpalmer jaredpalmer commented Nov 26, 2019

@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 } };
};
@neeharv

This comment has been minimized.

Copy link

@neeharv neeharv commented Nov 26, 2019

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.

@herrstucki

This comment has been minimized.

Copy link
Contributor

@herrstucki herrstucki commented Nov 26, 2019

@jaredpalmer I assume #9524 (comment) (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.)
@timneutkens

This comment has been minimized.

Copy link
Member Author

@timneutkens timneutkens commented Nov 26, 2019

@jaredpalmer tree shaking wasn't implemented yet on canary.

@baer

This comment has been minimized.

Copy link

@baer baer commented Nov 26, 2019

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 a exportPathMap 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:

  • User profile pages
  • Product pages (for companies with a fast-changing inventory)
  • Sales Order details pages

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

@timneutkens

This comment has been minimized.

Copy link
Member Author

@timneutkens timneutkens commented Nov 26, 2019

Are getStaticProps/getStaticPaths and getServerProps 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.

@jkjustjoshing

This comment has been minimized.

Copy link

@jkjustjoshing jkjustjoshing commented Nov 26, 2019

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)

@grushetsky

This comment has been minimized.

Copy link
Contributor

@grushetsky grushetsky commented Nov 28, 2019

@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:

  1. The app is packaged into a bundle: styles, scripts, images, index.html, certificates and TV config file.
  2. The bundle is submitted for review to platform’s app store.
  3. The bundle is then installed from the store as an app and is run by the user.

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.

@timneutkens

This comment has been minimized.

Copy link
Member Author

@timneutkens timneutkens commented Nov 28, 2019

@grushetsky can you create a different issue. This is a completely different question from what is being discussed in the RFC 👍

@outdooricon

This comment has been minimized.

Copy link

@outdooricon outdooricon commented Dec 3, 2019

@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?

@Timer

This comment has been minimized.

Copy link
Member

@Timer Timer commented Dec 3, 2019

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.

@Ephem

This comment has been minimized.

Copy link
Contributor

@Ephem Ephem commented Dec 4, 2019

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. 😄

@homoky

This comment has been minimized.

Copy link

@homoky homoky commented Dec 5, 2019

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.

@reaktivo

This comment has been minimized.

Copy link

@reaktivo reaktivo commented Dec 6, 2019

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?

@timneutkens

This comment has been minimized.

Copy link
Member Author

@timneutkens timneutkens commented Dec 7, 2019

@reaktivo pages/[lang]/blog/[id].js -> in getStaticPaths provide all urls to statically render.

@flawyte

This comment has been minimized.

Copy link

@flawyte flawyte commented Dec 7, 2019

@timneutkens Any idea when this will be available / testable?

@timneutkens

This comment has been minimized.

Copy link
Member Author

@timneutkens timneutkens commented Dec 8, 2019

In general we don't give out ETAs because we extensively test features against production apps to make sure the solution is right.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
You can’t perform that action at this time.