next.js: i18n with next export calls getStaticProps for each defined lang, but then errors

Bug report

Describe the bug

I’m attempting to use the brand new i18n feature for a static exported site. During build time it calls getStaticProps once for each lang defined in next.config.js and in some cases even builds the page, but at the end it fails with:

i18n support is not compatible with next export.

It feels like a tease having it almost build lol.

To Reproduce

Add langs to config

module.exports = {
	i18n: {
		locales: ['en-US', 'fr', 'nl-NL'],
		defaultLocale: 'en-US',
	},
}

Add getStaticProps to a page, like /content.tsx

export async function getStaticProps(context) {
	console.log('getStaticProps', context); // context will include the `locale` for each lang defined
	return {
		props: {},
	};
}

Expected behavior

To either:

Export all lang paths OR Fail early until this is better supported for next export

System information

  • OS: macOS
  • Version of Next.js: 10.0.0
  • Version of Node.js: 12.x

Additional context

Loaded env from /Users/REDACTED/gits/REDACTED/src/.env.production
info  - Using external babel configuration from /Users/REDACTED/gits/REDACTED/src/.babelrc
info  - Creating an optimized production build  
info  - Compiled successfully
info  - Collecting page data  
[   =] info  - Generating static pages (0/19){}
{}
{}
{}
[  ==] info  - Generating static pages (0/19)getStaticProps {
  locales: [ 'en-US', 'fr', 'nl-NL' ],
  locale: 'en-US',
  defaultLocale: 'en-US'
}
getStaticProps {
  locales: [ 'en-US', 'fr', 'nl-NL' ],
  locale: 'fr',
  defaultLocale: 'en-US'
}
getStaticProps {
  locales: [ 'en-US', 'fr', 'nl-NL' ],
  locale: 'nl-NL',
  defaultLocale: 'en-US'
}
{}
{}
{}
{}
info  - Generating static pages (19/19)
info  - Finalizing page optimization  

Page                                                           Size     First Load JS
┌ ○ /                                                          300 B           168 kB
├   /_app                                                      0 B             167 kB
├ ○ /404                                                       3.44 kB         171 kB
├ ● /content                                                   310 B           168 kB
├ ○ /foo                                                       300 B           168 kB
└ ○ /performance                                               297 B           168 kB
+ First Load JS shared by all                                  167 kB
  ├ chunks/d5fb258340a338fc09455890a68100a3d216cee4.6dfcc7.js  71 kB
  ├ chunks/f6078781a05fe1bcb0902d23dbbb2662c8d200b3.6547a9.js  11.4 kB
  ├ chunks/framework.a3ab6d.js                                 42.1 kB
  ├ chunks/main.fde44f.js                                      8.02 kB
  ├ chunks/pages/_app.6a0339.js                                34 kB
  ├ chunks/webpack.e06743.js                                   751 B
  └ css/afd7172b7cfc566ac23d.css                               20 B

λ  (Server)  server-side renders at runtime (uses getInitialProps or getServerSideProps)
○  (Static)  automatically rendered as static HTML (uses no initial props)
●  (SSG)     automatically generated as static HTML + JSON (uses getStaticProps)
   (ISR)     incremental static regeneration (uses revalidate in getStaticProps)

Loaded env from /Users/REDACTED/gits/REDACTED/src/.env.production
info  - using build directory: /Users/REDACTED/gits/REDACTED/src/.next
info  - Copying "static build" directory
info  - No "exportPathMap" found in "next.config.js". Generating map from "./pages"
Error: i18n support is not compatible with next export. See here for more info on deploying: https://nextjs.org/docs/deployment
    at exportApp (/Users/REDACTED/gits/REDACTED/src/node_modules/next/dist/export/index.js:14:296)

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 148
  • Comments: 52 (14 by maintainers)

Commits related to this issue

Most upvoted comments

Hi, as mentioned in the initial RFC next export wasn’t planned for initial support. When doing a build we don’t know that you’re going to call next export so we can’t show this error message earlier.

I’m going to close this since this is the expected behavior currently

It’s supported in the hybrid approach which the majority of Next.js applications uses. We can investigate adding next export support for it for you under enterprise support, feel free to reach out to enterprise@vercel.com

@ijjk You closed this issue a few months ago but it looks like many peeps still have an issue with this (myself included). What’s the preferred way to track interest in this feature (ideally publicly and not by sending emails around)? Should we create a new issue or feature request specifically for next export to support internationalized routing?

I see this as a huge drawback because it basically means that many companies (who want to host their Next.js projects on one of the many non-Vercel providers) cannot use Next.js with any modern i18n library anymore.

I’ve just spent some time implementing this to only realise you can’t use the next export command… why do the docs mislead us?

image

You can’t tell me that doesn’t suggest you can statically generate the i18n supported pages?

@timneutkens that’s a shame. Is there any kind of roadmap/timeline for adding full SSG support for i18n (even if it’s with language detection not supported)? Perhaps it’s worth updating the documentation to reflect the current level of support, because it definitely looks like it’s supported in the link above.

On a side note, I think this feature and the other new ones in Next.js 10 are totally awesome! Keep up the good work.

@caribou-code I did a quick investigation and it seems to be possible (but requires manual work, probably have to depend on a fork)… first of all you can disable the error that raises in next export command, this can be done by commenting out this block: https://github.com/vercel/next.js/blob/canary/packages/next/export/index.ts#L288-L292 (you can do that in the resulted file in node_modules too for testing (node_modules/next/dist/export/index.js -part of line 14-)

Then running yarn build and yarn export should work. The last step is that you need to change the out directory content, the export command generates the configurations for every language in your locales configuration correctly, but you need to move the defaultLocale to be in the root directory (to imitate nextjs default behaviour)… for example if your next.config.js have the following

  i18n: {
    locales: ["en", "de"],
    defaultLocale: "en",
  },

you need run the following commands

mv ./out/en.html ./out/index.html
mv ./out/en/*.html ./out/

then serving the out directory should work as expected

UPDATE: There were a lot of edge cases and it wasn’t stable enough to make a production release to test it out with this approach… So I’ve abandoned this for now… the code in this comment isn’t stable enough… it’s “working as expected” for tiny websites with not much edge cases and won’t be scaling to provide langauge cookie support, etc. etc.

@ijjk sorry I’m a bit confused, the documentation suggests that it’s supported here: https://nextjs.org/docs/advanced-features/i18n-routing#how-does-this-work-with-static-generation (if I’m not mistaken)… but I run into the same issue running next export

I’m also very confused. Both the docs and RFC suggest SSG support for i18n, and the SSG functions seem to support it on the surface (exposing locale in the context params) but not during export. This looks like a valid bug to me.

I just sent this whole week trying set up a repository for production and just found out that next export doesn’t support this. What a waste of time…

I noticed it’s actually mentioned at the very last paragraph in the documentation, but I wouldn’t have noticed that. Other pages have a dedicated section like “Caveats”. I believe this page should also have it and state more clearly that i18n is not supported with next export. I could have saved a lot of days.

This is really disappointing. Is there any workaround for using i18n with SSG in next?

I spent the day implementing i18n support in a project. Everything worked great during development. At the end of the day I went to generate the static files next export and found out the project would only work if it is hosted on Vercel’s platform. It is very sad to know that development is biased towards Vercel’s hosting 😦

@ijjk @timneutkens SSG with i18n needs to be in the roadmap if it isn’t already. This issue is blocking us from using or recommending NextJS as the framework of choice for statically hosted applications requiring i18n.

SSG with i18n is a must indeed, for me to continue using nextjs.

The problem is larger scale than this.

What is the i18n option?

  1. It is a routing shortcut. Somewhat equivalent to [locale]/normal/page/tree
  2. It adds utility methos for switching between languages.
  3. It is a server side feature to auto detect the language and redirect automatically.

But then there are plugins like next-i18next and next-translate

  • both force you to use the fairly new i18n routing feature ~ disabling the export feature
  • next-translate also uses rewrite rules to translate urls ~ putting an extra stop to the export feature

So what you actually want to do is ignore all the next plugins and the i18n routing option. Just build your page like this:

pages/
  [locale]/
    product/
      [id].js

And in the [locale]/product/[id].js, you define the routes like this:

export async function getStaticPaths() {
  const paths = [];
  for (const product of await somehowFetch('products')) {
    for (const locale of ['en', 'de']) {
      paths.push({params: {locale, id: product.id}})
    }
  }

  return {paths, fallback: false};
}

export async function getStaticProps({params: {id, locale}}) {
  const product = await somehowFetch(`product ${id}`);
  const translations = JSON.parse(await readFile(`translations.${locale}.json`));
  return {
    props: {product, translations, locale, locales: ['en', 'de']}
  };
}

And then you can decide if you need additional translation libraries like i18next or if you decide to just run props.translations.headline?.replace('%name%', props.product.name)

I was using static export to run nextjs app in capacitor project (hybrid app) and it worked well, but now it seems I cannot add i18n if next export won’t work, 🤔

I’m getting the same error and there is a lot of people who have the same issue.

It would be great to open this issue and take a look on it, because there is a lot of people that want to deploy their Next.js app using a non-Vercel CDN.

Also with the same i18n issue with export, quite disapointing, I thought Next.js was a nice alternative for small static sites, after a couple weeks of building my site I find that I cannot use the export option and the need to setup a node server.

Seems like you want devs to go into Vercel one way or the other. Next time I’ll give Nuxt a try.

Hi @timneutkens,

Next.js does statically generate pages when using the hybrid Next.js approach, which is the default and what the majority of Next.js applications uses. The i18n support goes much further than outputting static files for statically generated content, it also adds a routing layer and language detection layer which can’t be replicated with next export in a meaningful optimized way.

I understand that most Next.js apps are probably being hosted with Vercel or Netlify which will utilize the next build command only. My specific use case for next export is due to using the serverless-nexjts component to host a Next.js app with AWS directly. My build steps for this include next build && next export. I do think that there is a very valid need for being able to generate a simple purely static Next.js website that has i18n support.

I’ve moved the note about next export up in the static generation section: ad89993

Thank you for this!

As said if your company really needs this we can investigate building it out for you. I can’t prioritize adding next export support to i18n routing based on the current interest (18 👍’s on this issue) as there are much bigger optimizations on the roadmap. Furthermore, all the companies we talked to while building i18n support did not use next export.

Let the power of open-source go to work, then!

We can investigate adding next export support for it for you under enterprise support, feel free to reach out to enterprise@vercel.com

Appreciate the “plug”! 😂 But let’s keep this awesome framework focused on solving issues through open-source collaboration! I appreciate that others may be willing to pay for support on this, however, it’s not mission-critical enough for us right now.

Cheers!

Kyle

You can’t tell me that doesn’t suggest you can statically generate the i18n supported pages?

Next.js does statically generate pages when using the hybrid Next.js approach, which is the default and what the majority of Next.js applications uses. The i18n support goes much further than outputting static files for statically generated content, it also adds a routing layer and language detection layer which can’t be replicated with next export in a meaningful optimized way.

I’ve moved the note about next export up in the static generation section: https://github.com/vercel/next.js/commit/ad8999356d8c246619cace4e777acc0a7222c834

As said if your company really needs this we can investigate building it out for you. I can’t prioritize adding next export support to i18n routing based on the current interest (18 👍’s on this issue) as there are much bigger optimizations on the roadmap. Furthermore, all the companies we talked to while building i18n support did not use next export.

We can investigate adding next export support for it for you under enterprise support, feel free to reach out to enterprise@vercel.com

exporting i18n in next includes a big issues, but we couldn’t any right solution for a long time. Who should solve this problem? Should we give up using Next export? Smh… 🤣 There are a lot of questions about the next i18n export, but they didn’t answer with correct solution. Hoping there is a good news for them(including me) soon. 😥

Can’t believe this is not possible… Any new workaround for this? Or is it literally not possible to have a statically hosted multilanguage website when using next and i18n?

Is there any plan on adding i18n support with export?

@kylekirkby it definitely doesn’t.

I too got lost optimizing an existing website for i18n support, just to encounter that I cannot statically generate the pages. I’ve tried the @a14m solution, but I got weird, mixed, and non-complete export.

I’ll continue investigating, and will report here if I find some solution.

@chiqui3d check my starter, works with next export https://github.com/Xairoo/nextjs-i18n-static-page-starter I was looking for a static site solution to host the content anywhere. Also thought I will change back to PHP after trouble with Gatsby and Next.js, but I got a working solution. I tried to implement a i18n wrapper too, but stopped it fast until I run into problems. The current solution works and is totally okay for me, so no need to waste more time =)

The i18next-browser-languagedetector options are great if you need them.

I face this issue when I use next.js with https://github.com/isaachinman/next-i18next which is compatible with SSR. Is there any workaround for this error?

we also have this issue… tried the workaround… it isnt working… please help

I’ve just responded to the Vercel support with this (sharing this here mostly to inform you peeps about my implementation suggestion):

In my opinion, next export should simply export the properly-routed pages as static pages. This would restore a functionality that was working before when using Next.js in combination with next-i18next. I think what is happening now is that many people (there are 100 upvotes on the related issue today) migrated their projects to Next.js version 10 which required the new i18n routing, even when using a third-party library like next-i18next. I think it is fair to expect that there should be at least feature parity between those Next.js versions but a major feature (next export) is now unusable for many – hence the disappointment.

So, I’d really appreciate if the Next.js team considers to add exporting of i18n-enabled routes (without the language detection layer and whatever else cannot be replicated during the export). This would be my suggestion.

We are also facing this issue, did any one find a way to make localized pages be exported? we only need this on our mobile app that currently uses capacitor, so exporting localized pages would be important for us

I just sent this whole week trying set up a repository for production and just found out that next export doesn’t support this. What a waste of time…

Nearly the same for me. I wasted a lot of time with Gatsby. Until I decided to make the site a SEO friendly multi language site. Now trying Next.js because I think Gatsby is terrible for such cases if you want to have SEO friendly URLs (more or less dead i18n plugins).

I wanted to use SSG with react-intl, but now I am going with Next.js and using SSR.

It would be really awesome (and logic) that we could use internationalizing with SSG. react-intl also because of formatting numbers/dates.

Note: i18n routing does not currently support next export mode as you are no longer leveraging Next.js’ server-side routing.

This note should be on top of the site: https://nextjs.org/docs/advanced-features/i18n-routing

As @Nemo64 said, dynamic routing can be used to export static pages. I have a demo that uses react-i18next.

https://github.com/myWsq/nextjs-static-i18n

import { StaticI18nLink } from "../i18n-browser";
import { useTranslation } from "react-i18next";

const Layout: React.FunctionComponent = ({ children }) => {
  const { t } = useTranslation("common");

  return (
    <>
      <nav>
        <StaticI18nLink href="/">{t("home")}</StaticI18nLink>{" "}
        <StaticI18nLink href="/about">{t("about")}</StaticI18nLink>
      </nav>
      <main>{children}</main>
      <footer>
        <li>
          <StaticI18nLink locale="zh">简体中文</StaticI18nLink>
        </li>
        <li>
          <StaticI18nLink locale="en">English</StaticI18nLink>
        </li>
      </footer>
    </>
  );
};

export default Layout;

I’ve wrapped next/link to avoid using next international routing, but there are still boundary cases when using next/router. It’s a rudimentary approach, but it works well enough for me.

It also supports setting the basePath, and here is a deployment on Github Pages.

https://mywsq.github.io/nextjs-static-i18n

I spent the day implementing i18n support in a project. Everything worked great during development. At the end of the day I went to generate the static files next export and found out the project would only work if it is hosted on Vercel’s platform. It is very sad to know that development is biased towards Vercel’s hosting 😦

I don’t think anyone is limited to using the Vercel platform. Ultimately a Next.js project will either output static HTML files (which can be hosted anywhere, including an AWS S3 bucket for example) or it will require a running server (could be an AWS EC2 instance for example). The benefit of Vercel is it covers a lot of the hard work of doing the build and deployment correctly for you, and it handles the server-side stuff with Lambda@Edge functions, which is faster and cheaper to run. The issue in this particular case is that next export specifically doesn’t work with the new i18n integration.

I say the duplicate because the default language I use in the root of the domain, in addition each language has a different URL(/es/sobre-nosotros/, /en/about/), I do not use the same slug for all languages, that for me is to go a step back, go from PHP to Next.js to use the same URL. I better use Eleventy, which generates what I just give it. In short, Actually Next.js is not for SEO Ready as they say.