Closed kachkaev closed 4 years ago
Thanks, this is interesting work. I would consider some of this for a 1.x release, but currently core problems like #40 are taking top priority.
The proposed API layout could easily support next export
too. Here is a modified example from Next's README
:
// next.config.js
const { internationalizePathMap } = require('@next-i18next/based-on-path');
module.exports = {
exportPathMap: async function (defaultPathMap) {
return internationalizePathMap({
'/': { page: '/' },
'/about': { page: '/about' },
'/readme.md': { page: '/readme' },
'/p/hello-nextjs': { page: '/post', query: { title: 'hello-nextjs' } },
'/p/learn-nextjs': { page: '/post', query: { title: 'learn-nextjs' } },
'/p/deploy-nextjs': { page: '/post', query: { title: 'deploy-nextjs' } }
}, {
fallbackLanguage: 'en', // we don't have access to i18n.js here, so we need to remind Next what default language we use
availableLanguages: ['..', '..'], // the list is automatically derived by default from translation files
pathToTranslations: '...', // defaults to static/translations, just like in the middleware in server.js; only needed when availableLanguages are not defined (this can be linted in TypeScript)
})
}
}
Or in most cases:
// next.config.js
const { internationalizePathMap } = require('@next-i18next/based-on-path');
module.exports = {
exportPathMap: async function (defaultPathMap) {
return internationalizePathMap(defaultPathMap, {
fallbackLanguage: 'en',
availableLanguages: ['en', 'de'],
})
}
}
Internationalising next export
does not make sense for @next-i18next/based-on-user
(browser langauge detector), but can work pretty well for @next-i18next/based-on-path
. It is also potentially compatible with @next-i18next/based-on-host
– in this case either the host name or the language name can be prepended to output file paths. Despite a possible dependency to fs
in internationalizePathMap
, this module should not spill over to the browser as long as @next-i18next/based-on-(path|host)
provide a tree-shakeable esnext
version, which next build
can cope with.
To be clear, the proposed changes are not related to support of next export
- this is possible regardless. There's plenty else to focus on with this package, and supporting static exports isn't at the top of my list at the moment. It's certainly a "nice to have", though.
I'm just sharing my thoughts for the future – no attempts to re-prioritise your work whatsoever @isaachinman 😉
AFAIK, next export
simply takes a built version of next
, kind of starts the server and 'visits' all pages in the given path map. The result is dumped to a filesystem, that's it. There is a chance that I misunderstand the process, sorry if so.
UPD: looks like there is a problem with next export
+ custom server indeed: https://spectrum.chat/next-js/general/custom-server-with-static-html-export~1aabfe4c-7f93-4c94-9db7-a6223f441900. Nevertheless, this is something that's still possible to overcome with the right design (all we need is to stuff Next with translations during the export).
UPD2: Actually, this can be just
const { internationalizePathMap } = require('@next-i18next/static-export');
Injecting the translation data into query
should work regardless of the choice for @next-i18next/based-on-(user|path|host)
. The requirements to the output are the same in all cases: each language gets its own sub-path at the root of the export folder.
Number 1 priority remains tree walking and context issues. Until we come to a solid solution for that, this project is at a stand still.
Thanks for your proposals, we will revisit this in the (near, hopefully) future.
So, this a nice wish list, but there some problems, and some things would just be prohibitively hard to achieve. When responding, it would be helpful to use the numbers below so that it's clear which feature request we are discussing.
export const xxx
for typing: the core reason we're exporting a class constructor and returning methods inside of it is that we need to take the user-provided config, init an i18n
instance, and then share that instance with all methods. There is the possibility for a functional approach where the user handles the i18n
instance themselves and calls a bunch of createXXX
functions, but this involves a lot of unnecessary boilerplate for users, and also increases the chances of things breaking in user land. If there is a proposal that keeps initialisation to a one-liner, I am happy to hear it.pathToTranslations
is. Please let me know if I've misunderstood.__NEXT_DATA__
: if I understand this request correctly, you want to add things to pageProps
? That's not a problem, of course.browserLanguageDetection
, localeSubpaths
: again, we're not going to split into multiple packages anytime soon, so any desired fix will need to happen given the current structure. Also I'm not sure if you missed this, but both browserLanguageDetection
and localeSubpaths
depend on client side code. It's not a middleware.i18n.changeLanguage
if there's a language
prop on the Link
component, but this doesn't feel correct to me. Changing languages should be imperative. The Link
component is for routing, not changing user language.i18next
and react-i18next
if they want to do non-default stuff.next export
works just fine in next-i18next
. However, it's never going to be a main focus of this project, as SSR is a core part of the approach.In general this is not one proposal which will be accepted or rejected as a whole, but rather approximately ten proposals which will be appraised individually. Each individual proposal should (if we proceed with it) be accompanied by its own issue and PR.
Thanks for sharing your thoughts @isaachinman – I'll respond when I have more time to think on your comments. Meanwhile, could you please update the numbering in your reply so that it matched the items in my original list? I just replaced UL with OL there. Next export becomes number 11 instead of 10.
No rush with issue I guess. It's all about about the strategy, so I'm fine with a slow conversation pace.
@kachkaev Do you feel any/all of these points are still valid?
Hi @isaachinman! I'll be happy to look at the current state of things over the weekend 😉 Could you please sync the points in your comment with the list I shared originally? This is just so that everyone could easily refer to smth.
Hi @kachkaev Does this implementation of Language switching is closed to be released : https://github.com/kachkaev/next-i18n/blob/master/examples/basic/components/Menu.jsx ? I'm particularly concerned by this and the solution with Button doesn't fit my expectations (I need to navigate on language change to make some API calls in getInitialProps, not only fallback on locale files)
Thanks ;)
I'm going to close this now, as usage of next-i18next
and the API therein has settled and become fairly stable.
That being said, the API will probably completely change when this package is rewritten as a first-class NextJs plugin.
If anyone feels as though any of the suggestions mentioned here warrant more discussion, please open individual issues for them.
Following the discussions in https://github.com/isaachinman/next-i18next/issues/33, https://github.com/isaachinman/next-i18next/issues/32 and https://github.com/isaachinman/next-i18next/issues/16, I crafted a couple of examples that demonstrate how the usage of
next-i18next
could look like if the API was made more functional and less dependent on the config.https://github.com/kachkaev/next-i18n/tree/master/examples 👀
I don't have enough time before the weekend to describe all design justifications – let the examples speak for themselves. Here a few highlights though:
npm install @next-i18next/based-on-user @next-i18next/server-express
npm install @next-i18next/based-on-host @next-i18next/server-koa
Uninstall one module and install another one, modify module name in just one
require()
.i18n.js
are typescript/es6 compatible (usingexport const xxx
facilitates type checking and autocompletion in editors).withNamepaces
andTrans
insidei18n.js
reminds users to not import them directly fromreact-next18n
, which will cause issues.i18n.js
makes things more transparent and helps users understand what they can do with the library. No hidden object parts to re-use, as it is now (the current approach is also not typescript-compatible).server.js
, noti18n.js
. This means that no server-side files likeconfig.js
will be imported intoi18n.js
and so no IP will be accidentally leaked.pathToTranslations
etc. also lives inserver.js
as this is irrelevant for the client.__NEXT_DATA__
– no need to configure the client because of that.browserLanguageDetection
,localeSubpaths
orlocaleSubdomains
. Config options related to the middeware are passed on middleware creation insideserver.js
. The functional nature of the API makes it possible to type-check more things, e.g. the lack of ofhostByLanguage
inserver.ts
when@next-i18next/based-on-host
is used ini18n.js
✨<Link language="xx" href="/page" />
, where href is optional (current path by default).i18next
andreact-i18next
, which will not be in the list of direct project dependencies (doing so would make eslnt / tslint unhappy). Basically all the i18n bits and pieces the app may need are vividly declared ini18n.js
and are imported from there.i18next
andreact-i18next
are completely abstracted away in the eyes of a newcomer (people will be still encouraged to use https://locize.com/). Getting into details ofi18next
is only needed when you need some custom plugin like ICU.next export
see https://github.com/isaachinman/next-i18next/issues/42#issuecomment-447486698 and https://github.com/isaachinman/next-i18next/issues/42#issuecomment-447488552You'll probably notice that the examples refer to npm modules as
@next-i18n/*
, not@next-i18next/*
– it's me leaving myself an opportunity to make an alternative Next / I18next integration if this proposal is rejected 😅 I'd love to collaborate onnext-18next
, but if discussing the ideas ends up being challenging, I'm not sure I'll have enough mental energy to work on the PRs. Let's be polite to each other and thus attract more collaborators into the pool. ✌️WDYT about the proposed API layout in general? What are the flaws?