kit
kit copied to clipboard
i18n: localized / translated routes
This is now just a part of what #1037 implemented and also in a different way. The goal was to make alternate routes for the same page configurable.
There is a new configuration property "alternateRoutes" in the "kit" section of svelte.config.cjs. It optionally takes a function that receives a page's Part[][] and returns Part[][][], so the routes can be multiplied and the segments in Part[][] changed. This can be used e.g. to translate the routes or add a locale prefix.
Since the router has all the routes on the client, there is an alternates() function in "$app/navigation" that will return all alternate paths of a path. This is useful for language choosers for example.
I also added a usage example to "examples/svelte-kit-demo". Currently no translation is happening. This can be dealt with using translation libraries like svelte-i18n or svelte-intl-precompile.
@pz-mxu is attempting to deploy a commit to the Svelte Team on Vercel.
A member of the Team first needs to authorize it.
Answering here to some comments in #1037
@pz-mxu
I tried to create an extension point for routes. It currently fails to import svelte-intl-precompile into svelte.config.cjs due to "export * ...". Is there a workaround for that?
Maybe you're importing the runtime library instead of the built time plugin? Check this: https://github.com/cibernox/sveltekit-bug-with-plugin/blob/main/svelte.config.cjs
I know that your api is the same as for svelte-i18n, but if you compile the translations, wouldn't it be nicer to access them as object keys and functions with ts signature maybe? Like {$t.welcome(foo)} instead of {$t("welcome", { name: foo })}
I'm not so sure about that because it's very common for translations to have dashes for word separations (e.g. "header-title") and/or dots for namespacing (e.g. "forms.placeholders.name"), so invoking it with dot syntax would not be possible most of the time.
On that, since this library is the new kid in the block I wanted to make as easy as possible for people to give it a go. Svelte-i18n is by a fair margin the most popular library (and IMO the best too), so I chose to copy (sometimes literally copying chunks of code) from that one. I'm hesitant to come up with a new API when this one is so battle tested already.
@floratmin
First I thought the same, but except for javascript land the de facto standard is gettext. It is a little bit older and quirky but it has a superior workflow and a lot of tooling. When creating a multilingual site the workflow is extremely important. With gettext you get the following:
It's curious, my experience is exactly the opposite. Certainly in web the ICU message format is the most popular on the web (I am yet to see a web app using gettext), but even on android and iphone apps I never saw gettext used. I think I remember seeing it in a java project, but even on java the ICU message format is what I saw the most.
On those projects I worked with translation agencias and they seemed to have al the tooling they needed.
Regardless, the approach of my library is to compile translations into javascript functions ad build time, I think it would be amicable to supporting more than one i18n syntax like gettext or projectfluent, we'd just have to build a different plugin that can compile gettext po files into javascript functions.
@cibernox
gettext-to-messageformat compiles .po files to ICU message format and messageformat compiles ICU message format strings to javascript functions. These projects are created by the OpenJS foundation.
@floratmin I'm using messageformat already, but I'm using only the parser.
But it's great to know that gettext-to-messageformat can make easier to support gettext too.
Answering here to some comments in #1037
@pz-mxu
I tried to create an extension point for routes. It currently fails to import svelte-intl-precompile into svelte.config.cjs due to "export * ...". Is there a workaround for that?
Maybe you're importing the runtime library instead of the built time plugin? Check this: https://github.com/cibernox/sveltekit-bug-with-plugin/blob/main/svelte.config.cjs
I didn't mean the import for Vite plugin. When I want to translate route segments with a function that is invoked during manifest creation, I need access to the compiled translations at this point.
I may have to give it a go, I didn't consider importing translations from anywhere but application code. If you need to import it at build time for creating a manifest I need to check. If you can create a brach and link me to it I'll check it tonight.
I'm really excited to see this work. This is exactly the kind of thing I need to get an i18n app working smoothly. I know this is probably still a work in progress, but I wanted to provide some feedback after playing around with this.
Allow alternativeRoute to work for endpoints
Endpoints are often defined in the same directory as the page that uses it. It would be nice if you allow alternativeRoute to work for endpoints in addition to pages (I've added some proposed code changes here: https://github.com/pz-mxu/sveltekit/pull/1#issuecomment-827237120)
Allow dynamic and spread options to work from alternativeRoute
It looks like currently props are processed before alternativeRoute is ever used and because of that the dynamic and spread parameters, when added by alternativeRoute, doesn't work. https://github.com/sveltejs/kit/blob/3c81a326b8f268f274d0aede115a462bafe00585/packages/kit/src/core/create_manifest_data/index.js#L139-L140
it would be nice to have the option to add a dynamic segment like locale as a path parameter by doing something like:
alternateRoutes: (segments) => {
return [
segments,
// Ex. /{locale}/rest/of/path
[
[{ content: "locale", dynamic: true, spread: false }],
...segments
]
];
}
Ease of Use
I honestly am not 100% sure about this idea but I think we need a more intuitive way to work with configuring alternateRoutes. What if instead of using segments, alternateRoutes could be configured like this:
alternateRoutes: (path) => {
return [
path,
`/{locale}${path}`
];
}
I think this would align more with how a svelte-kit user thinks about routing. But I can see how using segments might be easier to manipulate?
Let me know what you think and if there is anything you would like me to help with, I'd love to contribute. Thanks
Allow
alternativeRouteto work for endpointsEndpoints are often defined in the same directory as the page that uses it. It would be nice if you allow
alternativeRouteto work for endpoints in addition to pages (I've added some proposed code changes here: pz-mxu#1 (comment))
Allowing it for endpoints is an option, but if we do that, the alternativeRoutes() function should also get the route's type. Some people might not want to localize endpoints.
Allow
dynamicandspreadoptions to work fromalternativeRouteIt looks like currently props are processed before
alternativeRouteis ever used and because of that thedynamicandspreadparameters, when added byalternativeRoute, doesn't work.https://github.com/sveltejs/kit/blob/3c81a326b8f268f274d0aede115a462bafe00585/packages/kit/src/core/create_manifest_data/index.js#L139-L140
it would be nice to have the option to add a dynamic segment like
localeas a path parameter by doing something like:alternateRoutes: (segments) => { return [ segments, // Ex. /{locale}/rest/of/path [ [{ content: "locale", dynamic: true, spread: false }], ...segments ] ]; }
Interesting idea, I haven't thought about that yet. Will try to add the possibility and we can play around with it.
Ease of Use
I honestly am not 100% sure about this idea but I think we need a more intuitive way to work with configuring
alternateRoutes. What if instead of usingsegments,alternateRoutescould be configured like this:alternateRoutes: (path) => { return [ path, `/{locale}${path}` ]; }I think this would align more with how a svelte-kit user thinks about routing. But I can see how using
segmentsmight be easier to manipulate?
I thought about that, too. But using the internal structure makes it easier to work with. Of course this way it's dependent on the internal structure of segments, that could maybe change some time. But I thought that the alternateRoutes() functions will probably be implemented by i18n-libraries, not directly by the user of svelte kit, although possible.
Just added another code change proposal: https://github.com/pz-mxu/sveltekit/pull/2#issue-624358833
I cleaned up the branch and rebased on the latest master.
What's the status on this branch? I'm interested by i18n routes
⚠️ No Changeset found
Latest commit: 64394c0d69e42f7627d4ab20ed584b2336dd96c3
Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.
This PR includes no changesets
When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types
Click here to learn what changesets are, and how to add one.
Click here if you're a maintainer who wants to add a changeset to this PR
I think this does some of the stuff implemented in #1810
I think this does some of the stuff implemented in #1810
You can not only use it to add the language to the route but also to translate the route. But it is not only usable for i18n.
❌ Deploy Preview for kit-demo failed.
🔨 Explore the source changes: 729357c252ff91aca62816b30e6b62f985aa2d45
🔍 Inspect the deploy log: https://app.netlify.com/sites/kit-demo/deploys/61d868c3ff7b0f000811e642
✔️ Deploy Preview for kit-demo canceled.
🔨 Explore the source changes: dd524622465c7c96752d886b9e3c67b81e2917bd
🔍 Inspect the deploy log: https://app.netlify.com/sites/kit-demo/deploys/61f80cb475268200085e3223
Yes please 😍 any news on this PR? seems a little abandoned? I'd really love to be able to translate routes in some way or another 🥰