Open axelvaindal opened 2 months ago
Hi @axelvaindal, have you found a solution? Looking forward!
@miguelmanteigueiro the best solution I've found is to pass the i18n instance via Inertia's shared props.
# config/inertia.ts
import { defineConfig } from '@adonisjs/inertia'
export default defineConfig({
/**
* Path to the Edge view that will be used as the root view for Inertia responses
*/
rootView: 'inertia_layout',
/**
* Data that should be shared with all rendered pages
*/
sharedData: {
user: (ctx) => ctx.auth?.user?.serialize({ fields: ['id', 'email'] }),
errors: (ctx) => ctx.session.flashMessages.get('errors'),
notification: (ctx) => ctx.session.flashMessages.get('notification'),
i18n: (ctx) => {
return {
...ctx.i18n,
locale: ctx.i18n.locale,
}
},
},
/**
* Options for the server-side rendering
*/
ssr: {
enabled: true,
entrypoint: 'inertia/app/ssr.tsx',
},
})
I'll try to optimize that later.
@miguelmanteigueiro the best solution I've found is to pass the i18n instance via Inertia's shared props.
# config/inertia.ts import { defineConfig } from '@adonisjs/inertia' export default defineConfig({ /** * Path to the Edge view that will be used as the root view for Inertia responses */ rootView: 'inertia_layout', /** * Data that should be shared with all rendered pages */ sharedData: { user: (ctx) => ctx.auth?.user?.serialize({ fields: ['id', 'email'] }), errors: (ctx) => ctx.session.flashMessages.get('errors'), notification: (ctx) => ctx.session.flashMessages.get('notification'), i18n: (ctx) => { return { ...ctx.i18n, locale: ctx.i18n.locale, } }, }, /** * Options for the server-side rendering */ ssr: { enabled: true, entrypoint: 'inertia/app/ssr.tsx', }, })
I'll try to optimize that later.
Thanks! And how would one change the i18n in a view (e.g., Index.svelte) and change the shared prop? I've tried finding that information in Inertia documentation and Adonis but no cigar.
@miguelmanteigueiro I use a combination of custom header and cookie in a middleware :
# app/middleware/detect_user_locale_middleware.ts
import { I18n } from '@adonisjs/i18n'
import i18nManager from '@adonisjs/i18n/services/main'
import type { NextFn } from '@adonisjs/core/types/http'
import { type HttpContext, RequestValidator } from '@adonisjs/core/http'
export default class DetectUserLocaleMiddleware {
static {
RequestValidator.messagesProvider = (ctx) => {
return ctx.i18n.createMessagesProvider()
}
}
protected getRequestLocale(ctx: HttpContext) {
// Retrieve supported languages
const supportedLocales = i18nManager.supportedLocales()
// First, try to read the language from a custom header
const customHeaderLocale = ctx.request.header('X-User-Language')
// If the custom header exists and is a valid locale, use it
if (customHeaderLocale && supportedLocales.includes(customHeaderLocale)) {
return customHeaderLocale
}
// Then check the cookie
const cookieLocale = ctx.request.cookie('user-locale')
if (cookieLocale && supportedLocales.includes(cookieLocale)) {
return cookieLocale
}
// Fallback to the Accept-Language header if no valid custom header or cookie
const userLanguages = ctx.request.languages()
return i18nManager.getSupportedLocaleFor(userLanguages)
}
async handle(ctx: HttpContext, next: NextFn) {
const language = this.getRequestLocale(ctx)
// Update the cookie if necessary
if (!ctx.request.cookie('user-locale') || ctx.request.cookie('user-locale') !== language) {
ctx.response.cookie('user-locale', language, {
httpOnly: true,
path: '/',
maxAge: 60 * 60 * 24 * 30, // Example duration: 30 days
sameSite: true, // Improve cookie security
})
}
// Update the locale for this request
ctx.i18n = i18nManager.locale(language || i18nManager.defaultLocale)
ctx.containerResolver.bindValue(I18n, ctx.i18n)
return next()
}
}
/**
* Notify TypeScript about i18n property
*/
declare module '@adonisjs/core/http' {
export interface HttpContext {
i18n: I18n
}
}
Package version
1.0.0-25
Describe the bug
Hello,
I'm using Inertia with AdonisJS 6 and I need to create an internationalized version of the website. Notably, most of the static content must be translated.
With AdonisJS + Edge, it's fairly simple as all the code is processed client side.
However though, when I create a wrapper around
i18n
to be used in my React component, it imports the server side code which is not good.Is there any way to have a
t()
helper resolving the translations the same way we can do this in Edge ?If not, can you pinpoint me in the right direction in creating such a thing ?
Thanks 🙏.
Reproduction repo
No response