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

i18n with next export calls getStaticProps for each defined lang, but then errors #18318

Closed
sean256 opened this issue Oct 27, 2020 · 52 comments
Closed
Assignees
Milestone

Comments

@sean256
Copy link

sean256 commented Oct 27, 2020

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)
@Timer Timer added this to the iteration 11 milestone Oct 28, 2020
@Timer Timer added point: 2 and removed kind: bug labels Oct 30, 2020
@Timer Timer assigned timneutkens and ijjk and unassigned timneutkens Oct 30, 2020
@Timer Timer modified the milestones: iteration 11, iteration 12 Oct 30, 2020
@ijjk
Copy link
Member

ijjk commented Oct 30, 2020

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

@ijjk ijjk closed this as completed Oct 30, 2020
@a14m
Copy link
Contributor

a14m commented Nov 9, 2020

@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

@caribou-code
Copy link

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.

@timneutkens
Copy link
Member

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

@a14m
Copy link
Contributor

a14m commented Nov 9, 2020

Will try to reach out, but it is definitely an important feature since we need to deploy static websites to client managed infrastructure (S3 or hosting provider, which usually cannot support the hybrid approach, they usually serve static files)

@caribou-code
Copy link

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

@a14m
Copy link
Contributor

a14m commented Nov 9, 2020

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

@timneutkens
Copy link
Member

You're welcome to PR support for it to next export, however keep in mind it would have a bunch of edge cases, e.g. domains does not work, locale detection does not work etc.

@kylekirkby
Copy link

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?

@tomijovanoski
Copy link

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

kodiakhq bot pushed a commit that referenced this issue Nov 19, 2020
This adds a note about current `i18n` support and `next export` since it is not currently supported as was mentioned in the [initial RFC](#17078)

x-ref: #18318
@ListeH
Copy link

ListeH commented Nov 22, 2020

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

Have you find some solution? I run into same issue, need to export static next page with locales.. :(

@winston0410
Copy link

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

@tomijovanoski
Copy link

@ListeH sadly no. Time was an issue, so I temporarily deployed the i18n version to Vercel (on the free tier) and reconfigured the domain DNS entries.

Hopefully, I will get back at it soon.
Following if someone else will have a breakthrough.

RoNoMaD added a commit to RoNoMaD/embarcadere that referenced this issue Nov 25, 2020
- use getStaticProps instead of getInitialprops
- use getStaticPaths instead of exportPathMap
- knowned issue does not work with next export
vercel/next.js#18318
@chiqui3d

This comment has been minimized.

@saadaouad
Copy link

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.

@Yuripetusko
Copy link
Contributor

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, 🤔

@sven-ra
Copy link

sven-ra commented May 7, 2021

Is there any plan on adding i18n support with export?

@qoala-github
Copy link

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

@kayosouza
Copy link

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

@miloshavlicek
Copy link

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?

@johndev0711
Copy link

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

@packetstracer
Copy link

packetstracer commented Jun 12, 2021

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.

@gancena
Copy link

gancena commented Jul 12, 2021

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

@raphjatteau
Copy link

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

@baeteja
Copy link

baeteja commented Aug 1, 2021

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?

@netpedro-com
Copy link

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

@caribou-code
Copy link

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.

@Nemo64
Copy link

Nemo64 commented Aug 11, 2021

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)

@myWsq
Copy link

myWsq commented Aug 13, 2021

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

@adrai
Copy link

adrai commented Aug 13, 2021

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

@Nemo64 have you ever thought about creating a (static-)next-i18next module or trying to contribute to https://github.com/isaachinman/next-i18next to check if there's a possibility to offer your way as an alternative option?

@Nemo64
Copy link

Nemo64 commented Aug 16, 2021

I haven't, and I don't think there is much an external package can do.

  • If you export a completely static site: use the approach I showed above.
  • If you export a fully dynamic page (backend without SSR), use i18next directly and ignore all static props features.
  • If you don't export but use the server side, use the existing next-i18next package

Those are the use cases I know of.

Most needed improvements are within next here:

  • If getStaticProps would work in every situation (they don't work with dynamic routing without staticPaths), then it would be easier to make one of the existing packages work without the i18n routing feature.
  • Of course it would be nice if the i18n routing feature would work as well, but I guess the first issue prevents that.

And I don't work long enough with next to address those.

@adrai
Copy link

adrai commented Aug 16, 2021

all ok, I have tried to change the next-i18next example to work with your approach: i18next/next-i18next#1202 (comment)

@herrherrmann
Copy link

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.

@adrai
Copy link

adrai commented Sep 8, 2021

@herrherrmann this works also with next-i18next 😉

https://github.com/adrai/next-static-i18n-test

and this simpler example: https://github.com/adrai/next-i18next-static-example

with a new language-detector module: https://github.com/adrai/next-language-detector/tree/main/example

@iamchathu
Copy link

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

How are we going to host this in netlify?

@patrick-mcdougle
Copy link

Could someone who has a local fork of Next try changing: https://github.com/vercel/next.js/blob/canary/packages/next/export/index.ts#L333

to if (i18n && !options.buildExport && !!i18n.localeDetection) {

That is, force a user using next export to opt out of localeDetection (i.e. we know we're opting out of locale cookie / server redirects / domains) that it works? Do we run into the issue mentioned above?

Perhaps we can re-write how the server and router code behaves so we can get this working. Anyone know the code intimately enough to try this? This doesn't feel like it should be too hard. The initial i18n routing PR isn't that big.

@github-actions
Copy link
Contributor

This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 25, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests