-
-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Setup each page - init hook, export const blocking
, etc.
#6183
Comments
If I understand you correctly, it could work today for you, too, but you'd have to do |
@dummdidumm right, but honestly, I suppose |
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
export const blocking
, etc.
I'm going to drop here some background on prior art on how other frameworks, in this case Ember.js, approached this problem of having code that needs to run before the continues the boot process and that code may or may not be blocking. In Ember such code was put in The shade of meaning between Initializers also had names and accepted I just mention this because IMO Ember got this reasonably right. Sveltekit may decide to come up with a different abstraction, but it's good to know how others approached similar problems in the past. |
|
Another thing coming up from a discussion: When doing this in the root layout and the setup depends on things that are causing the load function to rerun, the setup code might be rerun when you don't want that. #6294 could also help with that. |
Having a hook like EDIT: Ruby on Rails even has a whole |
No need for this. Back a while ago, we had #6179. This causes |
@tcc-sejohnson that is very interesting. Do you know if this is intended behaviour and expected to stay or it just happens to be that way because of an implementation detail? If that's guaranteed I'll go ahead and update the documentation on my library, but I wouldn't like the rug to be pulled from under me. |
@cibernox No it's intended -- I purposefully made that PR because of the same use-cases as @sphinxc0re. It was created in response to #6147. |
@tcc-sejohnson then you made my day! Thanks for the heads up! |
So this should be documented then, right? |
Hah, that would close my issue from a looong time ago: #1753 |
@tcc-sejohnson thanks! I will try it, at least it sounds good. |
@tcc-sejohnson, unfortunately, using hooks.client.js is not working for me because I need access to request ( |
@stalkerg there is a section about i18n in the docs: https://kit.svelte.dev/docs/accessibility#the-lang-attribute 🤷🏼♂️ maybe it helps |
Here's what i've been experimenting with today: lang.ts import type { Handle, RequestEvent } from '@sveltejs/kit';
import {
init,
register,
waitLocale,
getLocaleFromAcceptLanguageHeader,
getLocaleFromNavigator
} from 'svelte-intl-precompile';
register('en', () => import('$locales/en'));
register('de', () => import('$locales/de'));
const DEFAULT_LOCALE = 'en';
// add this hook to your hooks.server.ts sequence
// and update app.html to use `<html lang="%lang%">`
export const setLocale: Handle = async ({ event, resolve }) => {
const lang = await loadLocale(event);
return resolve(event, {
transformPageChunk: ({ html }) => html.replace('%lang%', lang)
});
};
// call this function with await in hooks.client.ts
export async function loadLocale(event?) {
let locale = event ? getSSRLocale(event) : getClientLocale();
init({ initialLocale: locale, fallbackLocale: DEFAULT_LOCALE });
await waitLocale(locale);
return locale;
}
function getSSRLocale(event: RequestEvent) {
// prefer stored user locale, fall back to accept header and default
return (
event.locals.user?.locale ||
getLocaleFromAcceptLanguageHeader(event.request.headers.get('Accept-Language')) ||
DEFAULT_LOCALE
);
}
function getClientLocale() {
// html lang attr is set by SSR hook, so we just reuse that
// otherwise fall back to navigator or default
return document?.documentElement.lang || getLocaleFromNavigator() || DEFAULT_LOCALE;
} hooks.client.ts import { loadLocale } from './lang';
await loadLocale(); hooks.server.ts import { setLocale } from './lang';
export const handle: Handle = sequence(/*auth etc */, setLocale); Is this a valid approach? |
unfortunate side effect: you have to update your build target to |
Good solution @dominikg
If you don't want to use es2022, you could do this
in the root import { browser } from '$app/environment';
import { loadLocale } from '../lang';
export const load = async () => {
if (browser) {
await loadLocale();
}
}; This should work. |
@PatrickG, as I mentioned in the issue, it will work only if you add |
I was only talking about the solution @dominikg provided. Edit: nevermind, I forgot about that
|
@sphinxc0re thanks for the advice, it does not solve this issue, but help to more accurate handle language even now. |
My proposal would be an exported
Maybe the returned value could be the equivalent of |
@dominikg That is beautiful code. Thanks for providing that ! Going to try that out. |
it's still very actual, and even more, because |
@Rich-Harris Seems like we should close this issue and break it out into multiple parts. Some pieces of this have been fixed (i.e. "global config" can run in the |
the TLA solution i drafted above for async client init doesn't really work great with bundling, so one of the requirements would be an async client init hook. edit: this repo showcases it (still on sveltekit beta bit iirc nothing significant has changed related to this so it still holds true). |
@tcc-sejohnson my first message is very specific and still not solved. Maybe we must create a new task issues bounded to this one. IMHO this issue as feature request is good. |
Describe the problem
For i18n or similar subsystems, we should make initialization before any language things are needed, and for such initialization, we usually use a session (user language) and information from the HTTP request.
Before the new routing system was introduced, we were using the root __layout.svelte to do it, it's working well for SSR and CSR time.
I should mention that what i18n should be inited on the server side and init on the client side as well (or state should be send as is).
After migration to new routing, we lose one "transitional" place to init such thing because
+layout.js
can be called after+page.js
, and you must doawait parent()
in each page to avoid such race condition.For server-side only init, we have a good place it's
handle
inhooks.js
withevent.locals
it's an excellent way to init server only things like DB connection, but for things what should be a transition from SSR to CSR we have no place.I also have a similar issue for i18n implementation project what I use cibernox/svelte-intl-precompile#55
Describe the proposed solution
Maybe it's possible to do it more straightforwardly, but at least we need a global hook for what will be called on SSR and on CSR, after
+layout.server.js
but before+layout.js
and+page.js
.Alternatives considered
No response
Importance
would make my life easier
Additional Information
No response
The text was updated successfully, but these errors were encountered: