File tree Expand file tree Collapse file tree 9 files changed +78
-54
lines changed Expand file tree Collapse file tree 9 files changed +78
-54
lines changed Original file line number Diff line number Diff line change 1
1
import { getFormProps , getInputProps , useForm } from '@conform-to/react'
2
2
import { getZodConstraint , parseWithZod } from '@conform-to/zod'
3
+ import { type SEOHandle } from '@nasa-gcn/remix-seo'
3
4
import * as E from '@react-email/components'
4
5
import {
5
6
json ,
@@ -19,6 +20,10 @@ import { checkHoneypot } from '#app/utils/honeypot.server.ts'
19
20
import { EmailSchema , UsernameSchema } from '#app/utils/user-validation.ts'
20
21
import { prepareVerification } from './verify.server.ts'
21
22
23
+ export const handle : SEOHandle = {
24
+ getSitemapEntries : ( ) => null ,
25
+ }
26
+
22
27
const ForgotPasswordSchema = z . object ( {
23
28
usernameOrEmail : z . union ( [ EmailSchema , UsernameSchema ] ) ,
24
29
} )
@@ -163,7 +168,7 @@ export default function ForgotPasswordRoute() {
163
168
status = {
164
169
forgotPassword . state === 'submitting'
165
170
? 'pending'
166
- : form . status ?? 'idle'
171
+ : ( form . status ?? 'idle' )
167
172
}
168
173
type = "submit"
169
174
disabled = { forgotPassword . state !== 'idle' }
Original file line number Diff line number Diff line change 1
1
import { getFormProps , getInputProps , useForm } from '@conform-to/react'
2
2
import { getZodConstraint , parseWithZod } from '@conform-to/zod'
3
+ import { type SEOHandle } from '@nasa-gcn/remix-seo'
3
4
import {
4
5
json ,
5
6
type ActionFunctionArgs ,
@@ -23,6 +24,10 @@ import { useIsPending } from '#app/utils/misc.tsx'
23
24
import { PasswordSchema , UsernameSchema } from '#app/utils/user-validation.ts'
24
25
import { handleNewSession } from './login.server.ts'
25
26
27
+ export const handle : SEOHandle = {
28
+ getSitemapEntries : ( ) => null ,
29
+ }
30
+
26
31
const LoginFormSchema = z . object ( {
27
32
username : UsernameSchema ,
28
33
password : PasswordSchema ,
@@ -158,7 +163,7 @@ export default function LoginPage() {
158
163
< div className = "flex items-center justify-between gap-6 pt-3" >
159
164
< StatusButton
160
165
className = "w-full"
161
- status = { isPending ? 'pending' : form . status ?? 'idle' }
166
+ status = { isPending ? 'pending' : ( form . status ?? 'idle' ) }
162
167
type = "submit"
163
168
disabled = { isPending }
164
169
>
Original file line number Diff line number Diff line change 1
1
import { getFormProps , getInputProps , useForm } from '@conform-to/react'
2
2
import { getZodConstraint , parseWithZod } from '@conform-to/zod'
3
+ import { type SEOHandle } from '@nasa-gcn/remix-seo'
3
4
import {
4
5
json ,
5
6
redirect ,
@@ -16,6 +17,10 @@ import { useIsPending } from '#app/utils/misc.tsx'
16
17
import { PasswordAndConfirmPasswordSchema } from '#app/utils/user-validation.ts'
17
18
import { verifySessionStorage } from '#app/utils/verification.server.ts'
18
19
20
+ export const handle : SEOHandle = {
21
+ getSitemapEntries : ( ) => null ,
22
+ }
23
+
19
24
export const resetPasswordUsernameSessionKey = 'resetPasswordUsername'
20
25
21
26
const ResetPasswordSchema = PasswordAndConfirmPasswordSchema
@@ -119,7 +124,7 @@ export default function ResetPasswordPage() {
119
124
120
125
< StatusButton
121
126
className = "w-full"
122
- status = { isPending ? 'pending' : form . status ?? 'idle' }
127
+ status = { isPending ? 'pending' : ( form . status ?? 'idle' ) }
123
128
type = "submit"
124
129
disabled = { isPending }
125
130
>
Original file line number Diff line number Diff line change 1
1
import { getFormProps , getInputProps , useForm } from '@conform-to/react'
2
2
import { getZodConstraint , parseWithZod } from '@conform-to/zod'
3
+ import { type SEOHandle } from '@nasa-gcn/remix-seo'
3
4
import * as E from '@react-email/components'
4
5
import {
5
6
json ,
@@ -24,6 +25,10 @@ import { useIsPending } from '#app/utils/misc.tsx'
24
25
import { EmailSchema } from '#app/utils/user-validation.ts'
25
26
import { prepareVerification } from './verify.server.ts'
26
27
28
+ export const handle : SEOHandle = {
29
+ getSitemapEntries : ( ) => null ,
30
+ }
31
+
27
32
const SignupSchema = z . object ( {
28
33
email : EmailSchema ,
29
34
} )
@@ -158,7 +163,7 @@ export default function SignupRoute() {
158
163
< ErrorList errors = { form . errors } id = { form . errorId } />
159
164
< StatusButton
160
165
className = "w-full"
161
- status = { isPending ? 'pending' : form . status ?? 'idle' }
166
+ status = { isPending ? 'pending' : ( form . status ?? 'idle' ) }
162
167
type = "submit"
163
168
disabled = { isPending }
164
169
>
Original file line number Diff line number Diff line change 1
1
import { getFormProps , getInputProps , useForm } from '@conform-to/react'
2
2
import { getZodConstraint , parseWithZod } from '@conform-to/zod'
3
+ import { type SEOHandle } from '@nasa-gcn/remix-seo'
3
4
import { type ActionFunctionArgs } from '@remix-run/node'
4
5
import { Form , useActionData , useSearchParams } from '@remix-run/react'
5
6
import { HoneypotInputs } from 'remix-utils/honeypot/react'
@@ -12,6 +13,10 @@ import { checkHoneypot } from '#app/utils/honeypot.server.ts'
12
13
import { useIsPending } from '#app/utils/misc.tsx'
13
14
import { validateRequest } from './verify.server.ts'
14
15
16
+ export const handle : SEOHandle = {
17
+ getSitemapEntries : ( ) => null ,
18
+ }
19
+
15
20
export const codeQueryParam = 'code'
16
21
export const targetQueryParam = 'target'
17
22
export const typeQueryParam = 'type'
@@ -122,7 +127,7 @@ export default function VerifyRoute() {
122
127
/>
123
128
< StatusButton
124
129
className = "w-full"
125
- status = { isPending ? 'pending' : form . status ?? 'idle' }
130
+ status = { isPending ? 'pending' : ( form . status ?? 'idle' ) }
126
131
type = "submit"
127
132
disabled = { isPending }
128
133
>
Original file line number Diff line number Diff line change @@ -15,23 +15,32 @@ Here are two quick examples of how to customize the sitemap on a per-route basis
15
15
from the ` @nasa-gcn/remix-seo ` docs:
16
16
17
17
``` 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'
19
21
20
22
export const handle: SEOHandle = {
21
- getSitemapEntries : async (request ) => {
23
+ getSitemapEntries: serverOnly$ ( async (request ) => {
22
24
const blogs = await db .blog .findMany ()
23
25
return blogs .map ((blog ) => {
24
26
return { route: ` /blog/${blog .slug } ` , priority: 0.7 }
25
27
})
26
- },
28
+ }) ,
27
29
}
28
30
```
29
31
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
+
30
39
``` tsx
31
40
// 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'
33
42
34
- export let loader = ({ request }: LoaderFunctionArgs ) => {
43
+ export async function loader ({ request }: LoaderFunctionArgs ) {
35
44
/**/
36
45
}
37
46
You can’t perform that action at this time.
0 commit comments