From e8b8a646b750db924313f6b80fd008f13e6d4c10 Mon Sep 17 00:00:00 2001 From: pheralb Date: Tue, 28 May 2024 12:03:06 +0100 Subject: [PATCH] docs: update remix post --- src/posts/remix.md | 119 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 117 insertions(+), 2 deletions(-) diff --git a/src/posts/remix.md b/src/posts/remix.md index 0a9c458..5d4a493 100644 --- a/src/posts/remix.md +++ b/src/posts/remix.md @@ -1,7 +1,7 @@ --- title: Remix v2 Snippets description: Code snippets for Remix. -date: '2024-4-28' +date: '2024-5-28' category: 'Snippets' writing: false published: true @@ -113,4 +113,119 @@ module.exports = { }; ``` -Ready 🚀✨ \ No newline at end of file +## Dark mode with Tailwind CSS + +1. Install [**remix-themes**](https://github.com/abereghici/remix-themes) and [**clsx**](https://github.com/lukeed/clsx#readme): + +```bash +pnpm i remix-themes clsx -E +``` + +2. Enable `darkMode` option in the `tailwind.config.ts` file: + +```ts +const config = { + darkMode: ['class'], + //... +} satisfies Config; +``` + +3. Create a `session.server.tsx` file in /app folder with the following content: + +```tsx +import { createCookieSessionStorage } from '@remix-run/node'; // +import { createThemeSessionResolver } from 'remix-themes'; + +// You can default to 'development' if process.env.NODE_ENV is not set: +const isProduction = process.env.NODE_ENV === 'production'; + +const sessionStorage = createCookieSessionStorage({ + cookie: { + name: 'website-theme', // 👈 Cookie name. + path: '/', + httpOnly: true, + sameSite: 'lax', + secrets: ['s3cr3t'], + ...(isProduction ? { domain: 'my-website.com', secure: true } : {}), // 👈 Website URL. + }, +}); + +export const themeSessionResolver = createThemeSessionResolver(sessionStorage); +``` + +4. In `app/routes` folder, create a `action.set-theme.ts` file with the following content: + +```ts +import { createThemeAction } from 'remix-themes'; +import { themeSessionResolver } from '@/sessions.server'; // 👈 Import your session.server.tsx. + +export const action = createThemeAction(themeSessionResolver); +``` + +5. In `app/routes/root.tsx`... + +- ☁️ Use the loader to get the theme from server-side: + +```tsx +import type { LoaderFunctionArgs } from '@remix/node'; +import { themeSessionResolver } from './sessions.server'; + +export async function loader({ request }: LoaderFunctionArgs) { + const { getTheme } = await themeSessionResolver(request); + return { + theme: getTheme(), + }; +} +``` + +- 📦 Wrap the entire app using `ThemeProvider`: + +```tsx +import { ThemeProvider } from 'remix-themes'; +import { useLoaderData } from '@remix-run/react'; + +export default function AppWithProviders() { + const data = useLoaderData(); + return ( + + + + ); +} + +function App() { + return ( + + + + ); +} +``` + +- ✨ In your `` component, use the `useTheme` hook: + +```tsx +import { useLoaderData } from '@remix-run/react'; +import { PreventFlashOnWrongTheme, useTheme } from 'remix-themes'; +import clsx from 'clsx'; + +function App() { + const data = useLoaderData(); + const [theme] = useTheme(); + return ( + + + + + + + + + + + + + + ); +} +``` \ No newline at end of file