From 536fbc784754e0c446ea7d2bc8c56fd3f7a761ec Mon Sep 17 00:00:00 2001 From: Roberto Simonetti Date: Tue, 12 Mar 2024 20:55:35 +0100 Subject: [PATCH] Update docs & sample app --- README.md | 4 ++-- docs/quick-start.md | 5 +++++ docs/tutorial-routing-rewrite.md | 37 +++++++++++++++++++++++++------- docs/tutorial-routing.md | 37 +++++++++++++++++++++++++------- src/routes/layout.tsx | 14 ++++++++++++ src/routes/plugin.ts | 21 ++++++++++++------ 6 files changed, 93 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 9380979..ee61e00 100644 --- a/README.md +++ b/README.md @@ -200,10 +200,10 @@ Translates a path, an URL or an array of paths. The translating string can be in Validate `language[-script][-region]` - `extractFromUrl(route: URL)` -Extract lang from url +Extract prefix from url - `extractFromDomain(route: URL, domains: SpeakLocale[] | RewriteRouteOption[])` -Extract lang from domain +Extract lang/prefix from domain ### Testing - `QwikSpeakMockProvider` component provides the Speak context to test enviroments diff --git a/docs/quick-start.md b/docs/quick-start.md index 03346b9..dfdec83 100644 --- a/docs/quick-start.md +++ b/docs/quick-start.md @@ -107,6 +107,11 @@ _src/routes/plugin.ts_ import type { RequestHandler } from '@builder.io/qwik-city'; import { config } from '../speak-config'; +/** + * This middleware function must only contain the logic to set the locale, + * because it is invoked on every request to the server. + * Avoid redirecting or throwing errors here, and prefer layouts or pages + */ export const onRequest: RequestHandler = ({ request, locale }) => { const acceptLanguage = request.headers?.get('accept-language'); diff --git a/docs/tutorial-routing-rewrite.md b/docs/tutorial-routing-rewrite.md index 513d2ed..90389f0 100644 --- a/docs/tutorial-routing-rewrite.md +++ b/docs/tutorial-routing-rewrite.md @@ -88,11 +88,16 @@ Update `plugin.ts` in the root of the `src/routes` directory: _src/routes/plugin.ts_ ```typescript import type { RequestHandler } from "@builder.io/qwik-city"; -import { extractFromUrl, validateLocale } from 'qwik-speak'; +import { extractFromUrl, setSpeakContext, validateLocale } from 'qwik-speak'; import { config } from '../speak-config'; -export const onRequest: RequestHandler = ({ locale, error, url }) => { +/** + * This middleware function must only contain the logic to set the locale, + * because it is invoked on every request to the server. + * Avoid redirecting or throwing errors here, and prefer layouts or pages + */ +export const onRequest: RequestHandler = ({ locale, url }) => { let lang: string | undefined = undefined; const prefix = extractFromUrl(url); @@ -100,17 +105,32 @@ export const onRequest: RequestHandler = ({ locale, error, url }) => { if (prefix && validateLocale(prefix)) { // Check supported locales lang = config.supportedLocales.find(value => value.lang === prefix)?.lang; - // 404 error page - if (!lang) throw error(404, 'Page not found'); } else { lang = config.defaultLocale.lang; } + // Set Speak context (optional: set the configuration on the server) + setSpeakContext(config); + // Set Qwik locale locale(lang); }; ``` +If you want to handle errors or redirects due to the locale, use layouts or pages. For example you could add in `src/routes/layout.ts`: +```typescript +export const onRequest: RequestHandler = ({ locale, error, redirect }) => { + // E.g. 404 error page + if (!locale()) throw error(404, 'Page not found for requested locale'); + + // E.g. Redirect + // if (!locale()) { + // const getPath = localizePath(); + // throw redirect(302, getPath('/page', 'en-US')); // Let the server know the language to use + // } +}; +``` + ## Usage Add `index.tsx` with some translation, providing optional default values for each translation: `key@@[default value]`: @@ -401,12 +421,12 @@ Since the `de` language does not have a default domain, but we have associated a Update `plugin.ts` to get the language from the domain: ```typescript import type { RequestHandler } from '@builder.io/qwik-city'; -import { extractFromDomain, extractFromUrl, validateLocale } from 'qwik-speak'; +import { extractFromDomain, extractFromUrl, setSpeakContext, validateLocale } from 'qwik-speak'; import { config } from '../speak-config'; import { rewriteRoutes } from '../speak-routes'; -export const onRequest: RequestHandler = ({ locale, error, url }) => { +export const onRequest: RequestHandler = ({ locale, url }) => { let lang: string | undefined = undefined; const prefix = extractFromUrl(url); @@ -414,13 +434,14 @@ export const onRequest: RequestHandler = ({ locale, error, url }) => { if (prefix && validateLocale(prefix)) { // Check supported locales lang = config.supportedLocales.find(value => value.lang === prefix)?.lang; - // 404 error page - if (!lang) throw error(404, 'Page not found'); } else { // Extract from domain lang = extractFromDomain(url, rewriteRoutes) || config.defaultLocale.lang; } + // Set Speak context (optional: set the configuration on the server) + setSpeakContext(config); + // Set Qwik locale locale(lang); }; diff --git a/docs/tutorial-routing.md b/docs/tutorial-routing.md index dd83afd..2d26430 100644 --- a/docs/tutorial-routing.md +++ b/docs/tutorial-routing.md @@ -24,27 +24,47 @@ Now let's handle it. Update `plugin.ts` in the root of the `src/routes` director _src/routes/plugin.ts_ ```typescript import type { RequestHandler } from '@builder.io/qwik-city'; -import { validateLocale } from 'qwik-speak'; +import { setSpeakContext, validateLocale } from 'qwik-speak'; import { config } from '../speak-config'; -export const onRequest: RequestHandler = ({ params, locale, error }) => { +/** + * This middleware function must only contain the logic to set the locale, + * because it is invoked on every request to the server. + * Avoid redirecting or throwing errors here, and prefer layouts or pages + */ +export const onRequest: RequestHandler = ({ params, locale }) => { let lang: string | undefined = undefined; if (params.lang && validateLocale(params.lang)) { // Check supported locales lang = config.supportedLocales.find(value => value.lang === params.lang)?.lang; - // 404 error page - if (!lang) throw error(404, 'Page not found'); } else { lang = config.defaultLocale.lang; } + // Set Speak context (optional: set the configuration on the server) + setSpeakContext(config); + // Set Qwik locale locale(lang); }; ``` +If you want to handle errors or redirects due to the locale, use layouts or pages. For example you could add in `src/routes/layout.ts`: +```typescript +export const onRequest: RequestHandler = ({ locale, error, redirect }) => { + // E.g. 404 error page + if (!locale()) throw error(404, 'Page not found for requested locale'); + + // E.g. Redirect + // if (!locale()) { + // const getPath = localizePath(); + // throw redirect(302, getPath('/page', 'en-US')); // Let the server know the language to use + // } +}; +``` + ## Usage Add `index.tsx` with some translation, providing optional default values for each translation: `key@@[default value]`: @@ -271,23 +291,24 @@ Since the `de` language does not have a default domain, but we have associated a Update `plugin.ts` to get the language from the domain: ```typescript import type { RequestHandler } from '@builder.io/qwik-city'; -import { extractFromDomain, validateLocale } from 'qwik-speak'; +import { extractFromDomain, setSpeakContext, validateLocale } from 'qwik-speak'; import { config } from '../speak-config'; -export const onRequest: RequestHandler = ({ params, locale, error, url }) => { +export const onRequest: RequestHandler = ({ params, locale, url }) => { let lang: string | undefined = undefined; if (params.lang && validateLocale(params.lang)) { // Check supported locales lang = config.supportedLocales.find(value => value.lang === params.lang)?.lang; - // 404 error page - if (!lang) throw error(404, 'Page not found'); } else { // Extract from domain lang = extractFromDomain(url, config.supportedLocales) || config.defaultLocale.lang; } + // Set Speak context (optional: set the configuration on the server) + setSpeakContext(config); + // Set Qwik locale locale(lang); }; diff --git a/src/routes/layout.tsx b/src/routes/layout.tsx index 7297e03..38c7576 100644 --- a/src/routes/layout.tsx +++ b/src/routes/layout.tsx @@ -1,6 +1,9 @@ import { component$, Slot } from '@builder.io/qwik'; +import type { RequestHandler } from '@builder.io/qwik-city'; import { Header } from '../components/header/header'; +// import { localizePath } from '../../packages/qwik-speak/src/routing'; +// import { config } from '../speak-config'; export default component$(() => { return ( @@ -10,3 +13,14 @@ export default component$(() => { ); }); + +export const onRequest: RequestHandler = ({ locale, error }) => { + // E.g. 404 error page + if (!locale()) throw error(404, 'Page not found for requested locale'); + + // E.g. Redirect + // if (!locale()) { + // const getPath = localizePath(); + // throw redirect(302, getPath('/page', 'en-US')); // Let the server know the language to use + // } +}; diff --git a/src/routes/plugin.ts b/src/routes/plugin.ts index 38239ad..1517b71 100644 --- a/src/routes/plugin.ts +++ b/src/routes/plugin.ts @@ -1,21 +1,27 @@ import type { RequestHandler } from '@builder.io/qwik-city'; -import { validateLocale } from 'qwik-speak'; +import { setSpeakContext, validateLocale } from 'qwik-speak'; import { config } from '../speak-config'; //import { rewriteRoutes } from '../speak-routes'; -export const onRequest: RequestHandler = ({ params, locale, error }) => { +/** + * This middleware function must only contain the logic to set the locale, + * because it is invoked on every request to the server. + * Avoid redirecting or throwing errors here, and prefer layouts or pages + */ +export const onRequest: RequestHandler = ({ params, locale }) => { let lang: string | undefined = undefined; if (params.lang && validateLocale(params.lang)) { // Check supported locales lang = config.supportedLocales.find(value => value.lang === params.lang)?.lang; - // 404 error page - if (!lang) throw error(404, 'Page not found'); } else { lang = config.defaultLocale.lang; } + // Set Speak context (optional: set the configuration on the server) + setSpeakContext(config); + // Set Qwik locale locale(lang); }; @@ -24,7 +30,7 @@ export const onRequest: RequestHandler = ({ params, locale, error }) => { * Uncomment this lines to use url rewriting to translate paths. * Remove [..lang] from folders structure */ -// export const onRequest: RequestHandler = ({ locale, error, url }) => { +// export const onRequest: RequestHandler = ({ locale, url }) => { // let lang: string | undefined = undefined; // const prefix = extractFromUrl(url); @@ -32,12 +38,13 @@ export const onRequest: RequestHandler = ({ params, locale, error }) => { // if (prefix && validateLocale(prefix)) { // // Check supported locales // lang = config.supportedLocales.find(value => value.lang === prefix)?.lang; -// // 404 error page -// if (!lang) throw error(404, 'Page not found'); // } else { // lang = config.defaultLocale.lang; // } +// // Set Speak context (optional: set the configuration on the server) +// setSpeakContext(config); + // // Set Qwik locale // locale(lang); // };