Skip to content

Commit b2f899f

Browse files
committed
fix(seo): ignore pages from the sitemap and prepare config
1 parent 20f3a80 commit b2f899f

File tree

9 files changed

+78
-54
lines changed

9 files changed

+78
-54
lines changed

app/routes/_auth+/forgot-password.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { getFormProps, getInputProps, useForm } from '@conform-to/react'
22
import { getZodConstraint, parseWithZod } from '@conform-to/zod'
3+
import { type SEOHandle } from '@nasa-gcn/remix-seo'
34
import * as E from '@react-email/components'
45
import {
56
json,
@@ -19,6 +20,10 @@ import { checkHoneypot } from '#app/utils/honeypot.server.ts'
1920
import { EmailSchema, UsernameSchema } from '#app/utils/user-validation.ts'
2021
import { prepareVerification } from './verify.server.ts'
2122

23+
export const handle: SEOHandle = {
24+
getSitemapEntries: () => null,
25+
}
26+
2227
const ForgotPasswordSchema = z.object({
2328
usernameOrEmail: z.union([EmailSchema, UsernameSchema]),
2429
})
@@ -163,7 +168,7 @@ export default function ForgotPasswordRoute() {
163168
status={
164169
forgotPassword.state === 'submitting'
165170
? 'pending'
166-
: form.status ?? 'idle'
171+
: (form.status ?? 'idle')
167172
}
168173
type="submit"
169174
disabled={forgotPassword.state !== 'idle'}

app/routes/_auth+/login.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { getFormProps, getInputProps, useForm } from '@conform-to/react'
22
import { getZodConstraint, parseWithZod } from '@conform-to/zod'
3+
import { type SEOHandle } from '@nasa-gcn/remix-seo'
34
import {
45
json,
56
type ActionFunctionArgs,
@@ -23,6 +24,10 @@ import { useIsPending } from '#app/utils/misc.tsx'
2324
import { PasswordSchema, UsernameSchema } from '#app/utils/user-validation.ts'
2425
import { handleNewSession } from './login.server.ts'
2526

27+
export const handle: SEOHandle = {
28+
getSitemapEntries: () => null,
29+
}
30+
2631
const LoginFormSchema = z.object({
2732
username: UsernameSchema,
2833
password: PasswordSchema,
@@ -158,7 +163,7 @@ export default function LoginPage() {
158163
<div className="flex items-center justify-between gap-6 pt-3">
159164
<StatusButton
160165
className="w-full"
161-
status={isPending ? 'pending' : form.status ?? 'idle'}
166+
status={isPending ? 'pending' : (form.status ?? 'idle')}
162167
type="submit"
163168
disabled={isPending}
164169
>

app/routes/_auth+/reset-password.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { getFormProps, getInputProps, useForm } from '@conform-to/react'
22
import { getZodConstraint, parseWithZod } from '@conform-to/zod'
3+
import { type SEOHandle } from '@nasa-gcn/remix-seo'
34
import {
45
json,
56
redirect,
@@ -16,6 +17,10 @@ import { useIsPending } from '#app/utils/misc.tsx'
1617
import { PasswordAndConfirmPasswordSchema } from '#app/utils/user-validation.ts'
1718
import { verifySessionStorage } from '#app/utils/verification.server.ts'
1819

20+
export const handle: SEOHandle = {
21+
getSitemapEntries: () => null,
22+
}
23+
1924
export const resetPasswordUsernameSessionKey = 'resetPasswordUsername'
2025

2126
const ResetPasswordSchema = PasswordAndConfirmPasswordSchema
@@ -119,7 +124,7 @@ export default function ResetPasswordPage() {
119124

120125
<StatusButton
121126
className="w-full"
122-
status={isPending ? 'pending' : form.status ?? 'idle'}
127+
status={isPending ? 'pending' : (form.status ?? 'idle')}
123128
type="submit"
124129
disabled={isPending}
125130
>

app/routes/_auth+/signup.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { getFormProps, getInputProps, useForm } from '@conform-to/react'
22
import { getZodConstraint, parseWithZod } from '@conform-to/zod'
3+
import { type SEOHandle } from '@nasa-gcn/remix-seo'
34
import * as E from '@react-email/components'
45
import {
56
json,
@@ -24,6 +25,10 @@ import { useIsPending } from '#app/utils/misc.tsx'
2425
import { EmailSchema } from '#app/utils/user-validation.ts'
2526
import { prepareVerification } from './verify.server.ts'
2627

28+
export const handle: SEOHandle = {
29+
getSitemapEntries: () => null,
30+
}
31+
2732
const SignupSchema = z.object({
2833
email: EmailSchema,
2934
})
@@ -158,7 +163,7 @@ export default function SignupRoute() {
158163
<ErrorList errors={form.errors} id={form.errorId} />
159164
<StatusButton
160165
className="w-full"
161-
status={isPending ? 'pending' : form.status ?? 'idle'}
166+
status={isPending ? 'pending' : (form.status ?? 'idle')}
162167
type="submit"
163168
disabled={isPending}
164169
>

app/routes/_auth+/verify.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { getFormProps, getInputProps, useForm } from '@conform-to/react'
22
import { getZodConstraint, parseWithZod } from '@conform-to/zod'
3+
import { type SEOHandle } from '@nasa-gcn/remix-seo'
34
import { type ActionFunctionArgs } from '@remix-run/node'
45
import { Form, useActionData, useSearchParams } from '@remix-run/react'
56
import { HoneypotInputs } from 'remix-utils/honeypot/react'
@@ -12,6 +13,10 @@ import { checkHoneypot } from '#app/utils/honeypot.server.ts'
1213
import { useIsPending } from '#app/utils/misc.tsx'
1314
import { validateRequest } from './verify.server.ts'
1415

16+
export const handle: SEOHandle = {
17+
getSitemapEntries: () => null,
18+
}
19+
1520
export const codeQueryParam = 'code'
1621
export const targetQueryParam = 'target'
1722
export const typeQueryParam = 'type'
@@ -122,7 +127,7 @@ export default function VerifyRoute() {
122127
/>
123128
<StatusButton
124129
className="w-full"
125-
status={isPending ? 'pending' : form.status ?? 'idle'}
130+
status={isPending ? 'pending' : (form.status ?? 'idle')}
126131
type="submit"
127132
disabled={isPending}
128133
>

docs/seo.md

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,32 @@ Here are two quick examples of how to customize the sitemap on a per-route basis
1515
from the `@nasa-gcn/remix-seo` docs:
1616

1717
```tsx
18-
// routes/blog/$blogslug.tsx
18+
// routes/blog/_layout.tsx
19+
import { type SEOHandle } from '@nasa-gcn/remix-seo'
20+
import { serverOnly$ } from 'vite-env-only/macros'
1921

2022
export const handle: SEOHandle = {
21-
getSitemapEntries: async (request) => {
23+
getSitemapEntries: serverOnly$(async (request) => {
2224
const blogs = await db.blog.findMany()
2325
return blogs.map((blog) => {
2426
return { route: `/blog/${blog.slug}`, priority: 0.7 }
2527
})
26-
},
28+
}),
2729
}
2830
```
2931

32+
Note the use of
33+
[`vite-env-only/macros`](https://github.com/pcattori/vite-env-only). This is
34+
because `handle` is a route export object that goes in both the client as well
35+
as the server, but our sitemap function should only be run on the server. So we
36+
use `vite-env-only/macros` to make sure the function is removed for the client
37+
build. Support for this is pre-configured in the `vite.config.ts` file.
38+
3039
```tsx
3140
// in your routes/url-that-doesnt-need-sitemap
32-
import { SEOHandle } from '@nasa-gcn/remix-seo'
41+
import { type SEOHandle } from '@nasa-gcn/remix-seo'
3342

34-
export let loader = ({ request }: LoaderFunctionArgs) => {
43+
export async function loader({ request }: LoaderFunctionArgs) {
3544
/**/
3645
}
3746

0 commit comments

Comments
 (0)