diff --git a/app/routes/_seo+/robots[.]txt.ts b/app/routes/_seo+/robots[.]txt.ts
index 2abd727d..f252528f 100644
--- a/app/routes/_seo+/robots[.]txt.ts
+++ b/app/routes/_seo+/robots[.]txt.ts
@@ -1,9 +1,9 @@
import { generateRobotsTxt } from '@nasa-gcn/remix-seo'
import { type DataFunctionArgs } from '@remix-run/node'
+import { getDomainUrl } from '#app/utils/misc.tsx'
export function loader({ request }: DataFunctionArgs) {
- const origin = new URL(request.url).origin
return generateRobotsTxt([
- { type: 'sitemap', value: `${origin}/sitemap.xml` },
+ { type: 'sitemap', value: `${getDomainUrl(request)}/sitemap.xml` },
])
}
diff --git a/app/routes/_seo+/sitemap[.]xml.ts b/app/routes/_seo+/sitemap[.]xml.ts
index 98d61b38..d490b0fa 100644
--- a/app/routes/_seo+/sitemap[.]xml.ts
+++ b/app/routes/_seo+/sitemap[.]xml.ts
@@ -1,10 +1,12 @@
import { generateSitemap } from '@nasa-gcn/remix-seo'
+// @ts-expect-error - this does work, though it's not exactly a public API
import { routes } from '@remix-run/dev/server-build'
-import { type LoaderFunctionArgs } from '@remix-run/node'
+import { type DataFunctionArgs } from '@remix-run/node'
+import { getDomainUrl } from '#app/utils/misc.tsx'
-export function loader({ request }: LoaderFunctionArgs) {
+export function loader({ request }: DataFunctionArgs) {
return generateSitemap(request, routes, {
- siteUrl: new URL(request.url).origin,
+ siteUrl: getDomainUrl(request),
headers: {
'Cache-Control': `public, max-age=${60 * 5}`,
},
diff --git a/app/routes/admin+/cache.tsx b/app/routes/admin+/cache.tsx
index 403dc63a..7e836c9b 100644
--- a/app/routes/admin+/cache.tsx
+++ b/app/routes/admin+/cache.tsx
@@ -1,3 +1,4 @@
+import { type SEOHandle } from '@nasa-gcn/remix-seo'
import { json, redirect, type DataFunctionArgs } from '@remix-run/node'
import {
Form,
@@ -28,6 +29,10 @@ import {
} from '#app/utils/misc.tsx'
import { requireUserWithRole } from '#app/utils/permissions.ts'
+export const handle: SEOHandle = {
+ getSitemapEntries: () => null,
+}
+
export async function loader({ request }: DataFunctionArgs) {
await requireUserWithRole(request, 'admin')
const searchParams = new URL(request.url).searchParams
diff --git a/app/routes/settings+/profile.change-email.tsx b/app/routes/settings+/profile.change-email.tsx
index 2a94ff99..c1684975 100644
--- a/app/routes/settings+/profile.change-email.tsx
+++ b/app/routes/settings+/profile.change-email.tsx
@@ -1,5 +1,6 @@
import { conform, useForm } from '@conform-to/react'
import { getFieldsetConstraint, parse } from '@conform-to/zod'
+import { type SEOHandle } from '@nasa-gcn/remix-seo'
import * as E from '@react-email/components'
import { json, redirect, type DataFunctionArgs } from '@remix-run/node'
import { Form, useActionData, useLoaderData } from '@remix-run/react'
@@ -19,9 +20,11 @@ import { invariant, useIsPending } from '#app/utils/misc.tsx'
import { redirectWithToast } from '#app/utils/toast.server.ts'
import { EmailSchema } from '#app/utils/user-validation.ts'
import { verifySessionStorage } from '#app/utils/verification.server.ts'
+import { type BreadcrumbHandle } from './profile.tsx'
-export const handle = {
+export const handle: BreadcrumbHandle & SEOHandle = {
breadcrumb: Change Email,
+ getSitemapEntries: () => null,
}
const newEmailAddressSessionKey = 'new-email-address'
diff --git a/app/routes/settings+/profile.connections.tsx b/app/routes/settings+/profile.connections.tsx
index d09565d9..5ad946eb 100644
--- a/app/routes/settings+/profile.connections.tsx
+++ b/app/routes/settings+/profile.connections.tsx
@@ -1,3 +1,4 @@
+import { type SEOHandle } from '@nasa-gcn/remix-seo'
import {
json,
type DataFunctionArgs,
@@ -17,7 +18,7 @@ import { requireUserId } from '#app/utils/auth.server.ts'
import { resolveConnectionData } from '#app/utils/connections.server.ts'
import {
ProviderConnectionForm,
- ProviderName,
+ type ProviderName,
ProviderNameSchema,
providerIcons,
providerNames,
@@ -25,9 +26,11 @@ import {
import { prisma } from '#app/utils/db.server.ts'
import { invariantResponse } from '#app/utils/misc.tsx'
import { createToastHeaders } from '#app/utils/toast.server.ts'
+import { type BreadcrumbHandle } from './profile.tsx'
-export const handle = {
+export const handle: BreadcrumbHandle & SEOHandle = {
breadcrumb: Connections,
+ getSitemapEntries: () => null,
}
async function userCanDeleteConnections(userId: string) {
diff --git a/app/routes/settings+/profile.index.tsx b/app/routes/settings+/profile.index.tsx
index 92734338..d97b8999 100644
--- a/app/routes/settings+/profile.index.tsx
+++ b/app/routes/settings+/profile.index.tsx
@@ -1,5 +1,6 @@
import { conform, useForm } from '@conform-to/react'
import { getFieldsetConstraint, parse } from '@conform-to/zod'
+import { type SEOHandle } from '@nasa-gcn/remix-seo'
import { json, redirect, type DataFunctionArgs } from '@remix-run/node'
import { Link, useFetcher, useLoaderData } from '@remix-run/react'
import { z } from 'zod'
@@ -18,6 +19,10 @@ import { sessionStorage } from '#app/utils/session.server.ts'
import { NameSchema, UsernameSchema } from '#app/utils/user-validation.ts'
import { twoFAVerificationType } from './profile.two-factor.tsx'
+export const handle: SEOHandle = {
+ getSitemapEntries: () => null,
+}
+
const ProfileFormSchema = z.object({
name: NameSchema.optional(),
username: UsernameSchema,
diff --git a/app/routes/settings+/profile.password.tsx b/app/routes/settings+/profile.password.tsx
index 5dcf6cf9..de82a77d 100644
--- a/app/routes/settings+/profile.password.tsx
+++ b/app/routes/settings+/profile.password.tsx
@@ -1,5 +1,6 @@
import { conform, useForm } from '@conform-to/react'
import { getFieldsetConstraint, parse } from '@conform-to/zod'
+import { type SEOHandle } from '@nasa-gcn/remix-seo'
import { json, redirect, type DataFunctionArgs } from '@remix-run/node'
import { Form, Link, useActionData } from '@remix-run/react'
import { z } from 'zod'
@@ -16,9 +17,11 @@ import { prisma } from '#app/utils/db.server.ts'
import { useIsPending } from '#app/utils/misc.tsx'
import { redirectWithToast } from '#app/utils/toast.server.ts'
import { PasswordSchema } from '#app/utils/user-validation.ts'
+import { type BreadcrumbHandle } from './profile.tsx'
-export const handle = {
+export const handle: BreadcrumbHandle & SEOHandle = {
breadcrumb: Password,
+ getSitemapEntries: () => null,
}
const ChangePasswordForm = z
diff --git a/app/routes/settings+/profile.password_.create.tsx b/app/routes/settings+/profile.password_.create.tsx
index e5bc636e..befb2cee 100644
--- a/app/routes/settings+/profile.password_.create.tsx
+++ b/app/routes/settings+/profile.password_.create.tsx
@@ -1,5 +1,6 @@
import { conform, useForm } from '@conform-to/react'
import { getFieldsetConstraint, parse } from '@conform-to/zod'
+import { type SEOHandle } from '@nasa-gcn/remix-seo'
import { json, redirect, type DataFunctionArgs } from '@remix-run/node'
import { Form, Link, useActionData } from '@remix-run/react'
import { z } from 'zod'
@@ -11,9 +12,11 @@ import { getPasswordHash, requireUserId } from '#app/utils/auth.server.ts'
import { prisma } from '#app/utils/db.server.ts'
import { useIsPending } from '#app/utils/misc.tsx'
import { PasswordSchema } from '#app/utils/user-validation.ts'
+import { type BreadcrumbHandle } from './profile.tsx'
-export const handle = {
+export const handle: BreadcrumbHandle & SEOHandle = {
breadcrumb: Password,
+ getSitemapEntries: () => null,
}
const CreatePasswordForm = z
diff --git a/app/routes/settings+/profile.photo.tsx b/app/routes/settings+/profile.photo.tsx
index 5fc95aa6..9b6337f7 100644
--- a/app/routes/settings+/profile.photo.tsx
+++ b/app/routes/settings+/profile.photo.tsx
@@ -1,5 +1,6 @@
import { conform, useForm } from '@conform-to/react'
import { getFieldsetConstraint, parse } from '@conform-to/zod'
+import { type SEOHandle } from '@nasa-gcn/remix-seo'
import {
json,
redirect,
@@ -23,9 +24,11 @@ import {
useDoubleCheck,
useIsPending,
} from '#app/utils/misc.tsx'
+import { type BreadcrumbHandle } from './profile.tsx'
-export const handle = {
+export const handle: BreadcrumbHandle & SEOHandle = {
breadcrumb: Photo,
+ getSitemapEntries: () => null,
}
const MAX_SIZE = 1024 * 1024 * 3 // 3MB
diff --git a/app/routes/settings+/profile.tsx b/app/routes/settings+/profile.tsx
index 09f7df2d..fc4102e7 100644
--- a/app/routes/settings+/profile.tsx
+++ b/app/routes/settings+/profile.tsx
@@ -1,3 +1,4 @@
+import { type SEOHandle } from '@nasa-gcn/remix-seo'
import { json, type DataFunctionArgs } from '@remix-run/node'
import { Link, Outlet, useMatches } from '@remix-run/react'
import { z } from 'zod'
@@ -8,8 +9,12 @@ import { prisma } from '#app/utils/db.server.ts'
import { cn, invariantResponse } from '#app/utils/misc.tsx'
import { useUser } from '#app/utils/user.ts'
-export const handle = {
+export const BreadcrumbHandle = z.object({ breadcrumb: z.any() })
+export type BreadcrumbHandle = z.infer
+
+export const handle: BreadcrumbHandle & SEOHandle = {
breadcrumb: Edit Profile,
+ getSitemapEntries: () => null,
}
export async function loader({ request }: DataFunctionArgs) {
@@ -23,7 +28,7 @@ export async function loader({ request }: DataFunctionArgs) {
}
const BreadcrumbHandleMatch = z.object({
- handle: z.object({ breadcrumb: z.any() }),
+ handle: BreadcrumbHandle,
})
export default function EditUserProfile() {
diff --git a/app/routes/settings+/profile.two-factor.disable.tsx b/app/routes/settings+/profile.two-factor.disable.tsx
index 1b627f86..b6e5d255 100644
--- a/app/routes/settings+/profile.two-factor.disable.tsx
+++ b/app/routes/settings+/profile.two-factor.disable.tsx
@@ -1,3 +1,4 @@
+import { type SEOHandle } from '@nasa-gcn/remix-seo'
import { json, type DataFunctionArgs } from '@remix-run/node'
import { useFetcher } from '@remix-run/react'
import { Icon } from '#app/components/ui/icon.tsx'
@@ -7,10 +8,12 @@ import { requireUserId } from '#app/utils/auth.server.ts'
import { prisma } from '#app/utils/db.server.ts'
import { useDoubleCheck } from '#app/utils/misc.tsx'
import { redirectWithToast } from '#app/utils/toast.server.ts'
+import { type BreadcrumbHandle } from './profile.tsx'
import { twoFAVerificationType } from './profile.two-factor.tsx'
-export const handle = {
+export const handle: BreadcrumbHandle & SEOHandle = {
breadcrumb: Disable,
+ getSitemapEntries: () => null,
}
export async function loader({ request }: DataFunctionArgs) {
diff --git a/app/routes/settings+/profile.two-factor.index.tsx b/app/routes/settings+/profile.two-factor.index.tsx
index 22c92259..bb0cd155 100644
--- a/app/routes/settings+/profile.two-factor.index.tsx
+++ b/app/routes/settings+/profile.two-factor.index.tsx
@@ -1,4 +1,5 @@
import { generateTOTP } from '@epic-web/totp'
+import { SEOHandle } from '@nasa-gcn/remix-seo'
import { json, redirect, type DataFunctionArgs } from '@remix-run/node'
import { Link, useFetcher, useLoaderData } from '@remix-run/react'
import { Icon } from '#app/components/ui/icon.tsx'
@@ -8,6 +9,10 @@ import { prisma } from '#app/utils/db.server.ts'
import { twoFAVerificationType } from './profile.two-factor.tsx'
import { twoFAVerifyVerificationType } from './profile.two-factor.verify.tsx'
+export const handle: SEOHandle = {
+ getSitemapEntries: () => null,
+}
+
export async function loader({ request }: DataFunctionArgs) {
const userId = await requireUserId(request)
const verification = await prisma.verification.findUnique({
diff --git a/app/routes/settings+/profile.two-factor.tsx b/app/routes/settings+/profile.two-factor.tsx
index ae3eb614..7f5dfd19 100644
--- a/app/routes/settings+/profile.two-factor.tsx
+++ b/app/routes/settings+/profile.two-factor.tsx
@@ -1,9 +1,12 @@
+import { type SEOHandle } from '@nasa-gcn/remix-seo'
import { Outlet } from '@remix-run/react'
import { Icon } from '#app/components/ui/icon.tsx'
import { type VerificationTypes } from '#app/routes/_auth+/verify.tsx'
+import { type BreadcrumbHandle } from './profile.tsx'
-export const handle = {
+export const handle: BreadcrumbHandle & SEOHandle = {
breadcrumb: 2FA,
+ getSitemapEntries: () => null,
}
export const twoFAVerificationType = '2fa' satisfies VerificationTypes
diff --git a/app/routes/settings+/profile.two-factor.verify.tsx b/app/routes/settings+/profile.two-factor.verify.tsx
index 71a4f484..04829828 100644
--- a/app/routes/settings+/profile.two-factor.verify.tsx
+++ b/app/routes/settings+/profile.two-factor.verify.tsx
@@ -1,6 +1,7 @@
import { conform, useForm } from '@conform-to/react'
import { getFieldsetConstraint, parse } from '@conform-to/zod'
import { getTOTPAuthUri } from '@epic-web/totp'
+import { type SEOHandle } from '@nasa-gcn/remix-seo'
import { json, redirect, type DataFunctionArgs } from '@remix-run/node'
import {
Form,
@@ -18,10 +19,12 @@ import { requireUserId } from '#app/utils/auth.server.ts'
import { prisma } from '#app/utils/db.server.ts'
import { getDomainUrl, useIsPending } from '#app/utils/misc.tsx'
import { redirectWithToast } from '#app/utils/toast.server.ts'
+import { type BreadcrumbHandle } from './profile.tsx'
import { twoFAVerificationType } from './profile.two-factor.tsx'
-export const handle = {
+export const handle: BreadcrumbHandle & SEOHandle = {
breadcrumb: Verify,
+ getSitemapEntries: () => null,
}
const VerifySchema = z.object({
diff --git a/public/robots.txt b/public/robots.txt
deleted file mode 100644
index c2a49f4f..00000000
--- a/public/robots.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-User-agent: *
-Allow: /