diff --git a/app/entry.server.tsx b/app/entry.server.tsx deleted file mode 100644 index f270ab3f2..000000000 --- a/app/entry.server.tsx +++ /dev/null @@ -1,142 +0,0 @@ -/** - * By default, Remix will handle generating the HTTP Response for you. - * You are free to delete this file if you'd like to, but if you ever want it revealed again, you can run `npx remix reveal` ✨ - * For more information, see https://remix.run/file-conventions/entry.server - */ -import type { AppLoadContext, EntryContext } from '@remix-run/node' -import { createReadableStreamFromReadable } from '@remix-run/node' -import { RemixServer } from '@remix-run/react' -import isbot from 'isbot' -import { PassThrough } from 'node:stream' -import { renderToPipeableStream } from 'react-dom/server' - -import { otherRootRouteHandlers } from './otherRootRoutes.server' - -const ABORT_DELAY = 5_000 - -export default async function handleRequest( - request: Request, - responseStatusCode: number, - responseHeaders: Headers, - remixContext: EntryContext, - loadContext: AppLoadContext -) { - for (const handler of otherRootRouteHandlers) { - const otherRouteResponse = await handler(request, remixContext) - if (otherRouteResponse) return otherRouteResponse - } - - return isbot(request.headers.get('user-agent')) - ? handleBotRequest( - request, - responseStatusCode, - responseHeaders, - remixContext - ) - : handleBrowserRequest( - request, - responseStatusCode, - responseHeaders, - remixContext - ) -} - -function handleBotRequest( - request: Request, - responseStatusCode: number, - responseHeaders: Headers, - remixContext: EntryContext -) { - return new Promise((resolve, reject) => { - let shellRendered = false - const { pipe, abort } = renderToPipeableStream( - , - { - onAllReady() { - shellRendered = true - const body = new PassThrough() - const stream = createReadableStreamFromReadable(body) - - responseHeaders.set('Content-Type', 'text/html') - - resolve( - new Response(stream, { - headers: responseHeaders, - status: responseStatusCode, - }) - ) - - pipe(body) - }, - onShellError(error: unknown) { - reject(error) - }, - onError(error: unknown) { - responseStatusCode = 500 - // Log streaming rendering errors from inside the shell. Don't log - // errors encountered during initial shell rendering since they'll - // reject and get logged in handleDocumentRequest. - if (shellRendered) { - console.error(error) - } - }, - } - ) - - setTimeout(abort, ABORT_DELAY) - }) -} - -function handleBrowserRequest( - request: Request, - responseStatusCode: number, - responseHeaders: Headers, - remixContext: EntryContext -) { - return new Promise((resolve, reject) => { - let shellRendered = false - const { pipe, abort } = renderToPipeableStream( - , - { - onShellReady() { - shellRendered = true - const body = new PassThrough() - const stream = createReadableStreamFromReadable(body) - - responseHeaders.set('Content-Type', 'text/html') - - resolve( - new Response(stream, { - headers: responseHeaders, - status: responseStatusCode, - }) - ) - - pipe(body) - }, - onShellError(error: unknown) { - reject(error) - }, - onError(error: unknown) { - responseStatusCode = 500 - // Log streaming rendering errors from inside the shell. Don't log - // errors encountered during initial shell rendering since they'll - // reject and get logged in handleDocumentRequest. - if (shellRendered) { - console.error(error) - } - }, - } - ) - - setTimeout(abort, ABORT_DELAY) - }) -} diff --git a/app/otherRootRoutes.server.ts b/app/otherRootRoutes.server.ts deleted file mode 100644 index 5058ed3b8..000000000 --- a/app/otherRootRoutes.server.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { generateRobotsTxt, generateSitemap } from '@balavishnuvj/remix-seo' -import type { EntryContext } from '@remix-run/server-runtime' - -type Handler = ( - request: Request, - remixContext: EntryContext -) => Promise | null - -export const otherRootRoutes: Record = { - '/sitemap.xml': async (request, remixContext) => { - const origin = new URL(request.url).origin - return generateSitemap(request, remixContext, { - siteUrl: origin, - headers: { - 'Cache-Control': `public, max-age=${60 * 5}`, - }, - }) - }, - '/robots.txt': async (request) => { - const origin = new URL(request.url).origin - return generateRobotsTxt([ - { type: 'sitemap', value: `${origin}/sitemap.xml` }, - { type: 'disallow', value: '/user' }, - ]) - }, -} - -export const otherRootRouteHandlers: Array = [ - ...Object.entries(otherRootRoutes).map(([path, handler]) => { - return (request: Request, remixContext: EntryContext) => { - if (new URL(request.url).pathname !== path) return null - return handler(request, remixContext) - } - }), -] diff --git a/app/routes/$.ts b/app/routes/$.ts index 48a7ae6c1..a998d5141 100644 --- a/app/routes/$.ts +++ b/app/routes/$.ts @@ -1,4 +1,4 @@ -import type { SEOHandle } from '@balavishnuvj/remix-seo' +import type { SEOHandle } from '@nasa-gcn/remix-seo' import type { LoaderFunction } from '@remix-run/node' import type { BreadcrumbHandle } from '~/root/Title' diff --git a/app/routes/_auth.post_logout.tsx b/app/routes/_auth.post_logout.tsx index 394fee2bf..33392ef73 100644 --- a/app/routes/_auth.post_logout.tsx +++ b/app/routes/_auth.post_logout.tsx @@ -5,7 +5,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -import type { SEOHandle } from '@balavishnuvj/remix-seo' +import type { SEOHandle } from '@nasa-gcn/remix-seo' import { type LoaderFunctionArgs, redirect } from '@remix-run/node' import { Form, Link, useLoaderData } from '@remix-run/react' import { diff --git a/app/routes/_seo.robots[.]txt.ts b/app/routes/_seo.robots[.]txt.ts new file mode 100644 index 000000000..13c48ee8d --- /dev/null +++ b/app/routes/_seo.robots[.]txt.ts @@ -0,0 +1,17 @@ +/*! + * Copyright © 2023 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * SPDX-License-Identifier: Apache-2.0 + */ +import { generateRobotsTxt } from '@nasa-gcn/remix-seo' + +import { origin } from '~/lib/env.server' + +export function loader() { + return generateRobotsTxt([ + { type: 'sitemap', value: `${origin}/sitemap.xml` }, + { type: 'disallow', value: '/user' }, + ]) +} diff --git a/app/routes/_seo.sitemap[.]xml.ts b/app/routes/_seo.sitemap[.]xml.ts new file mode 100644 index 000000000..62d30767d --- /dev/null +++ b/app/routes/_seo.sitemap[.]xml.ts @@ -0,0 +1,21 @@ +/*! + * Copyright © 2023 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * SPDX-License-Identifier: Apache-2.0 + */ +import { generateSitemap } from '@nasa-gcn/remix-seo' +import { routes } from '@remix-run/dev/server-build' +import type { LoaderFunctionArgs } from '@remix-run/node' + +import { origin } from '~/lib/env.server' + +export function loader({ request }: LoaderFunctionArgs) { + return generateSitemap(request, routes, { + siteUrl: origin, + headers: { + 'Cache-Control': `public, max-age=${60 * 5}`, + }, + }) +} diff --git a/app/routes/quickstart.alerts.tsx b/app/routes/quickstart.alerts.tsx index 3ac594609..387f1d2f4 100644 --- a/app/routes/quickstart.alerts.tsx +++ b/app/routes/quickstart.alerts.tsx @@ -5,7 +5,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -import type { SEOHandle } from '@balavishnuvj/remix-seo' +import type { SEOHandle } from '@nasa-gcn/remix-seo' import { Form, Link, useSearchParams } from '@remix-run/react' import { Button, ButtonGroup, FormGroup, Label } from '@trussworks/react-uswds' import { useState } from 'react' diff --git a/app/routes/quickstart.code.tsx b/app/routes/quickstart.code.tsx index 44975b192..00f0931c0 100644 --- a/app/routes/quickstart.code.tsx +++ b/app/routes/quickstart.code.tsx @@ -5,7 +5,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -import type { SEOHandle } from '@balavishnuvj/remix-seo' +import type { SEOHandle } from '@nasa-gcn/remix-seo' import type { DataFunctionArgs } from '@remix-run/node' import { Form, Link, useLoaderData } from '@remix-run/react' import { Button, ButtonGroup, FormGroup } from '@trussworks/react-uswds' diff --git a/app/routes/quickstart.credentials.tsx b/app/routes/quickstart.credentials.tsx index 67e7750bc..2182f98a5 100644 --- a/app/routes/quickstart.credentials.tsx +++ b/app/routes/quickstart.credentials.tsx @@ -5,7 +5,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -import type { SEOHandle } from '@balavishnuvj/remix-seo' +import type { SEOHandle } from '@nasa-gcn/remix-seo' import type { DataFunctionArgs } from '@remix-run/node' import { useLoaderData } from '@remix-run/react' diff --git a/app/routes/unsubscribe.$jwt/route.tsx b/app/routes/unsubscribe.$jwt/route.tsx index ed0ff97d2..0edee36fc 100644 --- a/app/routes/unsubscribe.$jwt/route.tsx +++ b/app/routes/unsubscribe.$jwt/route.tsx @@ -5,7 +5,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -import type { SEOHandle } from '@balavishnuvj/remix-seo' +import type { SEOHandle } from '@nasa-gcn/remix-seo' import type { DataFunctionArgs } from '@remix-run/node' import { Form, diff --git a/app/routes/user._index.tsx b/app/routes/user._index.tsx index 214788c5b..53a3a38f0 100644 --- a/app/routes/user._index.tsx +++ b/app/routes/user._index.tsx @@ -6,7 +6,7 @@ * SPDX-License-Identifier: Apache-2.0 */ import { UpdateUserAttributesCommand } from '@aws-sdk/client-cognito-identity-provider' -import type { SEOHandle } from '@balavishnuvj/remix-seo' +import type { SEOHandle } from '@nasa-gcn/remix-seo' import type { DataFunctionArgs } from '@remix-run/node' import { useFetcher, useLoaderData } from '@remix-run/react' import { diff --git a/app/routes/user.credentials._index.tsx b/app/routes/user.credentials._index.tsx index 5c116cefb..ce1e202a7 100644 --- a/app/routes/user.credentials._index.tsx +++ b/app/routes/user.credentials._index.tsx @@ -5,7 +5,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -import type { SEOHandle } from '@balavishnuvj/remix-seo' +import type { SEOHandle } from '@nasa-gcn/remix-seo' import type { DataFunctionArgs } from '@remix-run/node' import { Link, useLoaderData } from '@remix-run/react' diff --git a/app/routes/user.credentials.edit.tsx b/app/routes/user.credentials.edit.tsx index 17ccd08bd..b7f3c81f9 100644 --- a/app/routes/user.credentials.edit.tsx +++ b/app/routes/user.credentials.edit.tsx @@ -5,7 +5,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -import type { SEOHandle } from '@balavishnuvj/remix-seo' +import type { SEOHandle } from '@nasa-gcn/remix-seo' import type { DataFunctionArgs } from '@remix-run/node' import { diff --git a/app/routes/user.credentials/route.ts b/app/routes/user.credentials/route.ts index f593e8238..1194a4dac 100644 --- a/app/routes/user.credentials/route.ts +++ b/app/routes/user.credentials/route.ts @@ -5,7 +5,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -import type { SEOHandle } from '@balavishnuvj/remix-seo' +import type { SEOHandle } from '@nasa-gcn/remix-seo' import type { BreadcrumbHandle } from '~/root/Title' diff --git a/app/routes/user.email._index/route.tsx b/app/routes/user.email._index/route.tsx index a2432b30e..c3f806b4f 100644 --- a/app/routes/user.email._index/route.tsx +++ b/app/routes/user.email._index/route.tsx @@ -5,7 +5,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -import type { SEOHandle } from '@balavishnuvj/remix-seo' +import type { SEOHandle } from '@nasa-gcn/remix-seo' import type { DataFunctionArgs } from '@remix-run/node' import { Link, useFetcher, useLoaderData } from '@remix-run/react' import { Button, ButtonGroup, Grid, Icon } from '@trussworks/react-uswds' diff --git a/app/routes/user.email.edit.tsx b/app/routes/user.email.edit.tsx index 4ae6d7686..4ace057db 100644 --- a/app/routes/user.email.edit.tsx +++ b/app/routes/user.email.edit.tsx @@ -5,7 +5,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -import type { SEOHandle } from '@balavishnuvj/remix-seo' +import type { SEOHandle } from '@nasa-gcn/remix-seo' import type { DataFunctionArgs } from '@remix-run/node' import { redirect } from '@remix-run/node' import { Form, Link, useLoaderData } from '@remix-run/react' diff --git a/app/routes/user.email/route.ts b/app/routes/user.email/route.ts index b5ab1593b..c6cb2603a 100644 --- a/app/routes/user.email/route.ts +++ b/app/routes/user.email/route.ts @@ -5,7 +5,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -import type { SEOHandle } from '@balavishnuvj/remix-seo' +import type { SEOHandle } from '@nasa-gcn/remix-seo' import type { BreadcrumbHandle } from '~/root/Title' diff --git a/app/routes/user.endorsements/route.tsx b/app/routes/user.endorsements/route.tsx index 029082f08..f2abab19a 100644 --- a/app/routes/user.endorsements/route.tsx +++ b/app/routes/user.endorsements/route.tsx @@ -5,7 +5,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -import type { SEOHandle } from '@balavishnuvj/remix-seo' +import type { SEOHandle } from '@nasa-gcn/remix-seo' import type { DataFunctionArgs } from '@remix-run/node' import { Link, useFetcher, useLoaderData } from '@remix-run/react' import { diff --git a/app/routes/user.password/route.tsx b/app/routes/user.password/route.tsx index 22b2f14be..f953a82ed 100644 --- a/app/routes/user.password/route.tsx +++ b/app/routes/user.password/route.tsx @@ -5,7 +5,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -import type { SEOHandle } from '@balavishnuvj/remix-seo' +import type { SEOHandle } from '@nasa-gcn/remix-seo' import type { DataFunctionArgs } from '@remix-run/node' import { useFetcher } from '@remix-run/react' import { diff --git a/app/routes/user.tsx b/app/routes/user.tsx index 1ae295349..1ecc9b6d6 100644 --- a/app/routes/user.tsx +++ b/app/routes/user.tsx @@ -5,7 +5,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -import type { SEOHandle } from '@balavishnuvj/remix-seo' +import type { SEOHandle } from '@nasa-gcn/remix-seo' import { NavLink, Outlet } from '@remix-run/react' import { GridContainer } from '@trussworks/react-uswds' diff --git a/package-lock.json b/package-lock.json index cbcc650db..5614990c7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,9 +8,9 @@ "license": "Apache-2.0", "dependencies": { "@architect/functions": "^5.3.4", - "@balavishnuvj/remix-seo": "github:lpsinger/remix-seo#prepare-remix-2.0.0", "@nasa-gcn/architect-functions-search": "^1.0.0", "@nasa-gcn/dynamodb-autoincrement": "^1.0.0", + "@nasa-gcn/remix-seo": "^2.0.0", "@octokit/request-error": "^5.0.0", "@octokit/rest": "^20.0.1", "@opensearch-project/opensearch": "^2.2.0", @@ -6112,18 +6112,6 @@ "node": ">=6.9.0" } }, - "node_modules/@balavishnuvj/remix-seo": { - "version": "1.0.1", - "resolved": "git+ssh://git@github.com/lpsinger/remix-seo.git#d6baa45c2cde2ffd7b875ee0cf4effab126a4946", - "license": "MIT", - "dependencies": { - "lodash": "^4.17.21" - }, - "peerDependencies": { - "@remix-run/react": "^1.0.0 || ^2.0.0", - "@remix-run/server-runtime": "^1.0.0 || ^2.0.0" - } - }, "node_modules/@bcoe/v8-coverage": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", @@ -7446,6 +7434,18 @@ "eslint": ">=7" } }, + "node_modules/@nasa-gcn/remix-seo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@nasa-gcn/remix-seo/-/remix-seo-2.0.0.tgz", + "integrity": "sha512-jawoxrjMMbFGgj20d61KblrQNkSFcW2yP7vWWQn2a+eK2J8uYYbw99j2GD7A4XbpQUxy7dg0yvRVsYYJ5uZnLQ==", + "dependencies": { + "lodash": "^4.17.21" + }, + "peerDependencies": { + "@remix-run/react": "^1.0.0 || ^2.0.0", + "@remix-run/server-runtime": "^1.0.0 || ^2.0.0" + } + }, "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { "version": "5.1.1-v1", "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", @@ -31229,13 +31229,6 @@ "to-fast-properties": "^2.0.0" } }, - "@balavishnuvj/remix-seo": { - "version": "git+ssh://git@github.com/lpsinger/remix-seo.git#d6baa45c2cde2ffd7b875ee0cf4effab126a4946", - "from": "@balavishnuvj/remix-seo@github:lpsinger/remix-seo#prepare-remix-2.0.0", - "requires": { - "lodash": "^4.17.21" - } - }, "@bcoe/v8-coverage": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", @@ -32131,6 +32124,14 @@ "dev": true, "requires": {} }, + "@nasa-gcn/remix-seo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@nasa-gcn/remix-seo/-/remix-seo-2.0.0.tgz", + "integrity": "sha512-jawoxrjMMbFGgj20d61KblrQNkSFcW2yP7vWWQn2a+eK2J8uYYbw99j2GD7A4XbpQUxy7dg0yvRVsYYJ5uZnLQ==", + "requires": { + "lodash": "^4.17.21" + } + }, "@nicolo-ribaudo/eslint-scope-5-internals": { "version": "5.1.1-v1", "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", diff --git a/package.json b/package.json index e9f775068..0f783f2d8 100644 --- a/package.json +++ b/package.json @@ -26,9 +26,9 @@ }, "dependencies": { "@architect/functions": "^5.3.4", - "@balavishnuvj/remix-seo": "github:lpsinger/remix-seo#prepare-remix-2.0.0", "@nasa-gcn/architect-functions-search": "^1.0.0", "@nasa-gcn/dynamodb-autoincrement": "^1.0.0", + "@nasa-gcn/remix-seo": "^2.0.0", "@octokit/request-error": "^5.0.0", "@octokit/rest": "^20.0.1", "@opensearch-project/opensearch": "^2.2.0",