sveltejs / kit

web development, streamlined
https://kit.svelte.dev
MIT License
18.49k stars 1.89k forks source link

`reroute` enhancements #11595

Open benmccann opened 8 months ago

benmccann commented 8 months ago

Describe the problem

Content will be available at two URLs when using reroute. E.g. https://kit.svelte.dev/docs and https://kit.svelte.dev/en/docs. This is detrimental for user experience and SEO, so you would have to redirect https://kit.svelte.dev/en/docs to https://kit.svelte.dev/docs. It could potentially be kind of clunky if you need to update two places everytime you want to use reroute. However, one benefit of using the current handle API is that you can choose what type of redirect you want or if you want to show a 404 page instead, so this may be the desired way to approach this issue.

People have also mentioned wanting to reroute using cookies, which the current API doesn't allow. E.g. you might put someone into an A/B test bucket and want to show them the same version of the page everytime. If it's just content it's easier to A/B test in the template with an if statement, but if you need to load different data then something like rerouting might be beneficial

Describe the proposed solution

Perhaps think about whether/if we'd like to update the API at all as part of 3.0. We could also think about whether we want these files to live in a src/kit directory or change the .client/.server portion of the filename, etc.

Alternatives considered

No response

Importance

nice to have

Additional Information

No response

paoloricciuti commented 8 months ago

Isn't the fact that the content is the same in two routes basically the main point of reroute? I want to have the same content in /en/something and in /it/qualcosa but i just want /[lang]/something in my codebase.

f-elix commented 8 months ago

From what I've seen it doesn't have to be that way. You could just have a [lang]/docs route, where the lang param is not optional, so that /docs returns a 404.

benmccann commented 8 months ago

Isn't the fact that the content is the same in two routes basically the main point of reroute? I want to have the same content in /en/something and in /it/qualcosa but i just want /[lang]/something in my codebase.

By same content, I mean same exact content - i.e. same language. In this example there's an optional lang parameter and I don't want people to be able to access the English version at two different URLs, but just a single URL.

From what I've seen it doesn't have to be that way. You could just have a [lang]/docs route, where the lang param is not optional, so that /docs returns a 404.

Sure, there are many ways to setup i18n, but I don't want to turn this into a thread about that. This issue is about how the reroute API should look.

paoloricciuti commented 8 months ago

Isn't the fact that the content is the same in two routes basically the main point of reroute? I want to have the same content in /en/something and in /it/qualcosa but i just want /[lang]/something in my codebase.

By same content, I mean same exact content - i.e. same language. In this example there's an optional lang parameter and I don't want people to be able to access the English version at two different URLs, but just a single URL.

From what I've seen it doesn't have to be that way. You could just have a [lang]/docs route, where the lang param is not optional, so that /docs returns a 404.

Sure, there are many ways to setup i18n, but I don't want to turn this into a thread about that. This issue is about how the reroute API should look.

Do you think that should be the job for reroute? I think that should be a concern of the developer. So once I setup reroute I should also make sure that the two routes are different in content (or maybe not because I want to have two routes with the same content for some reason)

dominikg commented 8 months ago

+1 to reroute with headers. It's not just A/B testing but maybe language stored in a cookie or wanting to use the Accept-Lanugage header.

It can work by providing the headers only on serverside in reroute. Client can get the language from <html lang="XX"> which should have been produced by SSR or prerendering.

import {browser} from '$app/environment';
export const reroute ({url,headers}) {
  const lang = (browser ? document.documentElement.lang : getLang({url,headers})) ?? defaultLang;
  return getRoutePath(url,lang); // localization mapping in here
}
dominikg commented 8 months ago

Additionally, reroute currently only provides a one-way mapping of an incoming url to a route, but usually you need the opposite direction too to be able to produce matching hrefs during ssr.

inlang/paraglide currently has a sveltekit adapter that uses a hardcoded [lang] in first path segment scheme, but this does not work for everyone.

To avoid lots of different userland implementations doing all the legwork it would be great if kit had an api that was similar to atob btoa where you can have both ways set.

dominikg commented 8 months ago

If reroute is used for localized routes, should it be easily possible to disallow the target route? eg if you have a localized about page in src/routes/about/+page.svelte and reroute /about to /ueber-uns for german with the reroute hook, /de/ueber-uns should return 200, but /de/about should be a 404.

is it sufficient to have an error(404) in getRoutePath(url,lang) from my example above in case it does not find a localized name for that url? This would require that the function has mappings for all routes in all supported languages, which can be quite a few depending on the application.

dominikg commented 8 months ago

doing ssr with <html lang="XX"> set is important regardless of i18n framework you end up using, as is knowing which lang is currently active during ssr and on the client. Are these generic and important enough that we provide first-class support for it in kit itself?

Antonio-Bennett commented 8 months ago

I thought the second part of the original proposal could alleviate this?