Settings
Supaplate comes with a settings feature that allows users to choose their preferred language as well as their preferred theme (light or dark).
In this section we will how they work and how to configure them.
How they work
Both the language and the theme preferences are stored in cookies.
In the loader
function of the app/root.tsx
file there is code that reads the cookies and gets the locale
and theme
values.
export async function loader({ request }: Route.LoaderArgs) {
// ...
const [{ getTheme }, locale] = await Promise.all([
themeSessionResolver(request),
i18next.getLocale(request),
])
return {
theme: getTheme(),
locale,
}
}
These two values are then put in the lang
and className
attributes of the <html>
tag of the app/root.tsx
file.
<html
lang={data?.locale ?? 'en'}
className={cn(theme ?? '', 'h-full')}
dir={i18n.dir()}
>
// ...
</html>
Locale Setting
The locale setting is powered by i18next
.
i18next
uses the lang
attribute in the <html>
tag to know which language to use.
Translation files
Translation files are stored in the ./app/locales
directory.
The files are named after the language code.
βββ en.tsβββ es.tsβββ ko.ts
Inside of each file you will put the translations for the strings you want to translate.
// en.ts
const en = {
home: {
title: 'Supaplate',
subtitle: "It's time to build!",
},
...
}
// es.ts
const es: Translation = {
home: {
title: 'Supaplate',
subtitle: 'Es hora de construir!',
},
...
}
const ko: Translation = {
home: {
title: "μννλ μ΄νΈ",
subtitle: "λΉλνλ μκ°μ΄μΌ!",
},
...
};
Using the translations
To use the translations you can use the useTranslation
hook.
import { useTranslation } from 'react-i18next'
import i18next from '~/core/lib/i18next.server'
export const meta: Route.MetaFunction = ({ data }) => {
return [
{ title: data?.title },
{ name: 'description', content: data?.subtitle },
]
}
export async function loader({ request }: Route.LoaderArgs) {
const t = await i18next.getFixedT(request)
return {
title: t('home.title'),
subtitle: t('home.subtitle'),
}
}
export default function Home() {
const { t } = useTranslation()
return <div>{t('home.title')}</div>
}
Type safety
To ensure type safety, you can use the Translation
type exported from the ./app/locales/types.ts
file.
export type Translation = {
home: {
title: string
subtitle: string
}
}
Whenever you want add a new translation, add it first in the Translation
type, this way you will get an error if you forget to add it to the translation files.
Theme Setting
To add styles for dark mode you can use Tailwind CSS's dark
modifier.
<div className="dark:bg-black"> ... </div>
You can read more about Tailwind CSS's dark mode here.
Modifying the settings
There are two components in the /core/components/
directory called lang-switcher.tsx
and theme-switcher.tsx
.
You can put them wherever you want in your application, by default they are displayed in the navigation bar.
lang-switcher.tsx
is used to change the language of the application by sending a POST request to the /api/settings/locale
route with a new locale in the search params.
And theme-switcher.tsx
is used to change the theme of the application by sending a POST request to the /api/settings/theme
route with a new theme in the search params.
Disabling the settings
If you want to disable a settings feature you can just hide the lang-switcher.tsx
or theme-switcher.tsx
component and the route that is used to change the settings.