Skip to content

Commit ec30ea0

Browse files
committed
progressively enhance theme switcher
Closes #762
1 parent 7a4da05 commit ec30ea0

File tree

1 file changed

+16
-3
lines changed

1 file changed

+16
-3
lines changed

app/routes/resources+/theme-switch.tsx

+16-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import { useForm, getFormProps } from '@conform-to/react'
22
import { parseWithZod } from '@conform-to/zod'
33
import { invariantResponse } from '@epic-web/invariant'
44
import { json, type ActionFunctionArgs } from '@remix-run/node'
5-
import { useFetcher, useFetchers } from '@remix-run/react'
5+
import { redirect, useFetcher, useFetchers } from '@remix-run/react'
6+
import { ServerOnly } from 'remix-utils/server-only'
67
import { z } from 'zod'
78
import { Icon } from '#app/components/ui/icon.tsx'
89
import { useHints } from '#app/utils/client-hints.tsx'
@@ -11,6 +12,8 @@ import { type Theme, setTheme } from '#app/utils/theme.server.ts'
1112

1213
const ThemeFormSchema = z.object({
1314
theme: z.enum(['system', 'light', 'dark']),
15+
// this is useful for progressive enhancement
16+
redirectTo: z.string().optional(),
1417
})
1518

1619
export async function action({ request }: ActionFunctionArgs) {
@@ -21,12 +24,16 @@ export async function action({ request }: ActionFunctionArgs) {
2124

2225
invariantResponse(submission.status === 'success', 'Invalid theme received')
2326

24-
const { theme } = submission.value
27+
const { theme, redirectTo } = submission.value
2528

2629
const responseInit = {
2730
headers: { 'set-cookie': setTheme(theme) },
2831
}
29-
return json({ result: submission.reply() }, responseInit)
32+
if (redirectTo) {
33+
return redirect(redirectTo, responseInit)
34+
} else {
35+
return json({ result: submission.reply() }, responseInit)
36+
}
3037
}
3138

3239
export function ThemeSwitch({
@@ -35,6 +42,7 @@ export function ThemeSwitch({
3542
userPreference?: Theme | null
3643
}) {
3744
const fetcher = useFetcher<typeof action>()
45+
const requestInfo = useRequestInfo()
3846

3947
const [form] = useForm({
4048
id: 'theme-switch',
@@ -69,6 +77,11 @@ export function ThemeSwitch({
6977
{...getFormProps(form)}
7078
action="/resources/theme-switch"
7179
>
80+
<ServerOnly>
81+
{() => (
82+
<input type="hidden" name="redirectTo" value={requestInfo.path} />
83+
)}
84+
</ServerOnly>
7285
<input type="hidden" name="theme" value={nextMode} />
7386
<div className="flex gap-2">
7487
<button

0 commit comments

Comments
 (0)