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

next export does not work #10

Closed
tizzle opened this issue Nov 29, 2018 · 17 comments
Closed

next export does not work #10

tizzle opened this issue Nov 29, 2018 · 17 comments

Comments

@tizzle
Copy link

tizzle commented Nov 29, 2018

Describe the bug
When doing a next export to built a static page, i get the following error:

TypeError: Cannot read property '0' of undefined
    at /Users/tillhinrichs/Documents/_DEVELOPER/HTML/CleanCleanShop/cc-next2/node_modules/next-i18next/dist/hocs/app-with-translation.js:155:68
    at Array.filter (<anonymous>)
    at _callee$ (/Users/tillhinrichs/Documents/_DEVELOPER/HTML/CleanCleanShop/cc-next2/node_modules/next-i18next/dist/hocs/app-with-translation.js:154:61)
    at tryCatch (/Users/tillhinrichs/Documents/_DEVELOPER/HTML/CleanCleanShop/cc-next2/node_modules/regenerator-runtime/runtime.js:62:40)
    at Generator.invoke [as _invoke] (/Users/tillhinrichs/Documents/_DEVELOPER/HTML/CleanCleanShop/cc-next2/node_modules/regenerator-runtime/runtime.js:288:22)
    at Generator.prototype.(anonymous function) [as next] (/Users/tillhinrichs/Documents/_DEVELOPER/HTML/CleanCleanShop/cc-next2/node_modules/regenerator-runtime/runtime.js:114:21)
    at asyncGeneratorStep (/Users/tillhinrichs/Documents/_DEVELOPER/HTML/CleanCleanShop/cc-next2/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:24)
    at _next (/Users/tillhinrichs/Documents/_DEVELOPER/HTML/CleanCleanShop/cc-next2/node_modules/@babel/runtime/helpers/asyncToGenerator.js:25:9)
    at /Users/tillhinrichs/Documents/_DEVELOPER/HTML/CleanCleanShop/cc-next2/node_modules/@babel/runtime/helpers/asyncToGenerator.js:32:7
    at new Promise (<anonymous>)

To Reproduce
Steps to reproduce the behavior:

  1. Clone or download this repository
  2. In terminal do cd example
  3. Install dependencies: yarn
  4. I had to install next-i18next as well: yarn add next-i18next
  5. Check if it runs in dev: yarn run dev -> Works
  6. Check if it builds: yarn run next build -> Works
  7. Check if it exports: yarn run next export -> Fails

Expected behaviour
A static version of the app/page should be built.

OS (please complete the following information):

  • Device: MacBook Pro (15-inch, 2017)
  • Browser: Chrome Version 70.0.3538.110
@isaachinman
Copy link
Contributor

Interesting issue. I protected a couple of the language logic areas with simple if statements and got export working just fine.

That said, this project isn't really friendly to next export as it specifically requires some server side logic to detect language, fetch translation files, and so on. There's no way to do SSR translations without some server logic.

I'm curious as to how you expected this to work? Perhaps I'm missing something?

The only workable "solution" I can think of is to have the server render nothing, and the client can successfully fetch translated content as needed. This would depend upon NextJs exposing some sort of env var to indicate that an export is being run.

@tizzle
Copy link
Author

tizzle commented Nov 29, 2018

Hey @isaachinman,

Thanks for your prompt reply and for the great work on all things i18next.

My maybe naïve expectation was, that the export would write translated strings to static html. The resulting app/site would then have a set of pages for the defaultLanguage and another set of pages for every additional language inside a lang-folder (e.g. de).

I'm pretty sure there once was a react-i18next example for nextjs that exported like that.

But thinking about it a little more, i see that language switching might prove a bit tricky in that scenario in terms of keeping the route and not linking to /.

I will search for that example and see if it really exports as described above.

Thanks again and best regards!

Till

@isaachinman
Copy link
Contributor

Ah, I see. That would indeed be very cool. I see two main problems with that:

1. Too opinionated

This approach would really only work with the localeSubpaths routing paradigm, which is a very opinionated approach, and just one way to handle routing with languages. Many people prefer subdomains, query params, and so on. It would be a big investment of development time for a feature that only helps a small portion of people

2. Requires build-step changes

This would also require serious build-time changes, as we'd need to essentially run next export n times, wherein n is your number of locales, each time somehow injecting that locale into the build process so we know which language to render, and then putting that out content into a subdir. I'm not entirely sure that's even possible, and if it was it'd certainly require some complex webpack overrides that I'd rather not get into.

All of that said, if you can find that example I would be very interested to see the approach. Regardless of all of this, I think I can get next export working in a way where the server delivers an empty page, and the client will pick it up. This is certainly not a real solution, but at least it will degrade gracefully.

Let me know what you think.

@isaachinman
Copy link
Contributor

isaachinman commented Nov 29, 2018

@tizzle I added my initial thoughts on a branch called support-next-export.

The aforementioned graceful degradation of SSR seems to be working fine. However, I realised that of course the localeSubpaths functionality won't work after an export, as the subpaths no longer exist, because we're not running an express server. I thought Next might do some fancy stuff and generate static routes based on our server.get calls, but that's not the case.

In short, it's sort of a lose-lose. I need to think awhile on this. Regardless of how we proceed, it will definitely be important to include this information in the README. My initial feeling is that we should just not support next export at all.

@jamuhl
Copy link
Member

jamuhl commented Nov 29, 2018

the react-i18next sample had a working export but that did not generate files per language - just the client did fetch the missing translations from /static/ and rendered (no server - no SSR)

edit: And yes - no subpaths at that time

@tizzle
Copy link
Author

tizzle commented Nov 29, 2018

Hi @isaachinman,

i think nextjs leaves the custom path definitions for exports to the user. There is a thing called exportPathMap you can put into next.config.js.

You can see this in action here: https://github.com/zeit/next.js/blob/canary/examples/with-static-export/next.config.js

For next-i18next this would be the place where the localeSubpaths had to be added. As i see it, this would definitely mean some manual work on the users' side and thus making the super minimal setup of this package more complex.

I also think the aforementioned static export example that worked as i expected made heavy use of this.

Maybe this helps to provide some export capabilities. I will also think about this a bit more.

@isaachinman
Copy link
Contributor

@jamuhl Then, that is exactly what is achieved on the support-next-export branch.

I suppose we can merge this if users really want it, but it seems like it misses the entire point to me. Also, if you want to have a static translated website with NextJs, you might as well just create all the routes manually with the content directly inside the React components, and do a next export - basically don't use i18next at all...

@jamuhl
Copy link
Member

jamuhl commented Nov 30, 2018

@isaachinman yes...misses the point - at that point (😄) in react-i18next sample i wasn't in the mood anylonger to argue about it making sense -> just let them do the export and have that clientside react app ;)

@tizzle
Copy link
Author

tizzle commented Nov 30, 2018

Hey @isaachinman and @jamuhl,

i totally agree with you that the benefits of a static export are very small. Maybe a prominent statement in the README would be enough to make this clear. Feel free to close. Thanks for your discussion.

@isaachinman
Copy link
Contributor

This is fixed with #15.

Now, doing next export in a next-i18next project will result in a clientside-only React application.

No future plans to support any kind of custom export process with locale subdirs.

@elbotho
Copy link
Contributor

elbotho commented Jun 4, 2019

If someone full export:
Those two issues contain some hints:
vercel/next.js#2665
vercel/next.js#5509

@balazsorban44
Copy link

@isaachinman Is this (particularly getStaticPaths) any help here? vercel/next.js#9524

@isaachinman
Copy link
Contributor

@balazsorban44 Yes, I believe getStaticPath could be used to aid the static generation of next-i18next apps.

@balazsorban44
Copy link

I will try by myself, but if you have a good idea of how this could be achieved, I would be happy to look at your take! 🙂

@7iomka
Copy link

7iomka commented May 9, 2020

@balazsorban44 Yes, I believe getStaticPath could be used to aid the static generation of next-i18next apps.

Will be nice to see any example of this!

@hrahimi270
Copy link

@isaachinman I have a different problem here. But I think it's related.
When I use next build & next start everything is ok.
But, when I use next export, it builds without exit code thus it has errors on browser console and the translation is not working fine.
While Next is trying to run the export command, logs this:
Exporting (0/15)react-i18next:: i18n.languages were undefined or empty undefined.
Any idea on that?

@michchan
Copy link

michchan commented Mar 18, 2021

My workaround for SSG (next export) app with next-i18next (Next v10):

  1. Setup according to the Get Started guide by next-i18next
  2. Remove i18n in next.config.js
  3. Move pages/index.js (or any page except _app and _document) to pages/[[locale]]/index.js
  4. Add getStaticPaths like this:
export async function getStaticPaths() {
  return {
    paths: i18n.locales.map(locale => ({ params: { locale } })),
    fallback: false,
  }
}
  1. Change getStaticProps to be like this:
export async function getStaticProps({ params }) {
  const locale = params?.locale || i18n.defaultLocale
  return {
    props: {
      ...await serverSideTranslations(locale, ['common']),
    },
  }
}
  1. Now it should work on both next dev and next build && next export when you navigate to pathname /en (or any other locale you specified)
  2. To get / redirect to /en on client-side (or any other default locale), add the following pages/index.js:
import { useRouter } from 'next/router'
import { i18n } from '../next-i18next.config'

const HomeFallback = () => {
  const router = useRouter()
  // Make sure we're in the browser
  if (typeof window !== 'undefined')
    // @TODO: Use locale on localStorage / browser preference
    router.replace(`${i18n.defaultLocale}/${router.pathname}`)

  return null 
}

export default HomeFallback 

Checkout my sample repo: michchan/next-i18next-ssg-workaround@0caac9e

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants