Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate superflare and @superflare/remix from remix v2 → react-router v7 #75

Open
wants to merge 26 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
51390e0
Cleanup additional defunct JSON config flags
acusti Jan 17, 2025
c834819
Apply toJSON() to relations (stop password leak)
acusti Jan 21, 2025
80ed4bf
Add explicit toJSON() method to queries
acusti Jan 21, 2025
3e59403
Add single fetch serialization ownKeys proxy trap
acusti Jan 21, 2025
4e94c50
Migrate to single fetch (prep for rr v7)
acusti Jan 17, 2025
b63ea4f
Refactor Model+QueryBuilder types for single fetch
acusti Jan 22, 2025
185c6cc
Remove relation promise union → improve Model type
acusti Jan 22, 2025
0007acb
Remove defunct build.d.ts files, add GH env var
acusti Jan 17, 2025
8665ffb
📝 Fix typos/grammar in docs and comments
acusti Jan 22, 2025
89878fc
Update publish-snapshot.yml to get latest corepack
acusti Feb 7, 2025
962f911
Remove relation promise union → improve Model type
acusti Jan 22, 2025
810d971
Remove deprecated @remix-run/eslint-config
acusti Jan 17, 2025
1e38a95
Migrate examples/remix-cms to RR v7
acusti Jan 17, 2025
ba75927
Migrate templates/remix to RR v7
acusti Jan 17, 2025
181876a
Migrate apps/site to RR v7
acusti Jan 17, 2025
b1b6645
Update lock file with RR v7 dependency changes
acusti Jan 17, 2025
dbe3f85
Upgrade @cloudflare/workers-types + tsup
acusti Jan 19, 2025
9e09e1a
Adapt superflare from remix → react-router
acusti Jan 20, 2025
ed63075
:memo: Update docs from remix → react-router
acusti Jan 20, 2025
e01605b
Update unused pages function example to latest API
acusti Jan 21, 2025
e6830bf
Add react-router to typegen command
acusti Jan 22, 2025
15b4549
Migrate docs site/remix-cms/template to RR types
acusti Jan 22, 2025
4dbe4db
Return seed callback to enable awaiting result
acusti Jan 22, 2025
27900ea
Bump eslint(-register) dependencies
acusti Jan 27, 2025
1314eda
Use @mjackson/node-fetch-server for viteDevServer
acusti Feb 6, 2025
01f7b77
Adopt latest entry.(client|server).tsx examples
acusti Feb 7, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/publish-snapshot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
- name: Checkout code
uses: actions/checkout@v2

- run: corepack enable
- run: npm install -g corepack@latest && corepack enable
- uses: actions/setup-node@v4
with:
node-version: 20
Expand Down
1 change: 1 addition & 0 deletions apps/site/.env.example
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
DOCSEARCH_APP_ID=RETR9S9VHS
DOCSEARCH_API_KEY=326c1723a310dfe29004b47608709907
DOCSEARCH_INDEX_NAME=tailwindui-protocol
GITHUB_TOKEN=foo
2 changes: 1 addition & 1 deletion apps/site/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,5 @@ node_modules
/public/build
.env
/.wrangler

.react-router/
.dev.vars
2 changes: 1 addition & 1 deletion apps/site/app/components/Button.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Link } from "@remix-run/react";
import { Link } from "react-router";
import clsx from "clsx";

const styles = {
Expand Down
2 changes: 1 addition & 1 deletion apps/site/app/components/Layout.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useCallback, useEffect, useState } from "react";
import { Link, useLocation } from "@remix-run/react";
import { Link, useLocation } from "react-router";
import clsx from "clsx";

import { Hero } from "~/components/Hero";
Expand Down
2 changes: 1 addition & 1 deletion apps/site/app/components/MobileNavigation.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useEffect, useState } from "react";
import { Link, useNavigation } from "@remix-run/react";
import { Link, useNavigation } from "react-router";
import { Dialog } from "@headlessui/react";

import { Logomark } from "~/components/Logo";
Expand Down
2 changes: 1 addition & 1 deletion apps/site/app/components/Navigation.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Link, useLocation } from "@remix-run/react";
import { Link, useLocation } from "react-router";
import clsx from "clsx";
import { Manifest } from "~/docs.server";

Expand Down
2 changes: 1 addition & 1 deletion apps/site/app/components/QuickLinks.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Link } from "@remix-run/react";
import { Link } from "react-router";

import { Icon } from "./Icon";

Expand Down
2 changes: 1 addition & 1 deletion apps/site/app/components/Search.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useCallback, useEffect, useState } from "react";
import { createPortal } from "react-dom";
import { Link, useNavigate } from "@remix-run/react";
import { Link, useNavigate } from "react-router";
import { DocSearchModal, useDocSearchKeyboardEvents } from "@docsearch/react";

function Hit({ hit, children }: { hit: any; children: any }) {
Expand Down
51 changes: 51 additions & 0 deletions apps/site/app/entry.server.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/**
* 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 { isbot } from "isbot";
import { renderToReadableStream } from "react-dom/server";
import {
type AppLoadContext,
type EntryContext,
ServerRouter,
} from "react-router";

export default async function handleRequest(
request: Request,
responseStatusCode: number,
responseHeaders: Headers,
routerContext: EntryContext
) {
let shellRendered = false;
const userAgent = request.headers.get("user-agent");

const body = await renderToReadableStream(
<ServerRouter context={routerContext} url={request.url} />,
{
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);
}
},
}
);
shellRendered = true;

// Ensure requests from bots and SPA Mode renders wait for all content to load before responding
// https://react.dev/reference/react-dom/server/renderToPipeableStream#waiting-for-all-content-to-load-for-crawlers-and-static-generation
if ((userAgent && isbot(userAgent)) || routerContext.isSpaMode) {
await body.allReady;
}

responseHeaders.set("Content-Type", "text/html");
return new Response(body, {
headers: responseHeaders,
status: responseStatusCode,
});
}
14 changes: 6 additions & 8 deletions apps/site/app/root.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
import {
json,
type LinksFunction,
type MetaFunction,
type LoaderFunctionArgs,
} from "@remix-run/cloudflare";
import {
Links,
Meta,
Outlet,
Scripts,
ScrollRestoration,
useLoaderData,
} from "@remix-run/react";
} from "react-router";
import "@docsearch/css";
import "focus-visible";
import "./styles/tailwind.css";

import type { Route } from "./routes/+types/_index";

export const meta: MetaFunction = () => [
{ title: "Superflare", "twitter:title": "Superflare" },
{ viewport: "width=device-width,initial-scale=1" },
Expand Down Expand Up @@ -45,14 +43,14 @@ export const links: LinksFunction = () => [
},
];

export async function loader({ context: { cloudflare } }: LoaderFunctionArgs) {
return json({
export async function loader({ context: { cloudflare } }: Route.LoaderArgs) {
return {
ENV: {
DOCSEARCH_APP_ID: cloudflare.env.DOCSEARCH_APP_ID,
DOCSEARCH_API_KEY: cloudflare.env.DOCSEARCH_API_KEY,
DOCSEARCH_INDEX_NAME: cloudflare.env.DOCSEARCH_INDEX_NAME,
},
});
};
}

const themeScript = `
Expand Down
4 changes: 4 additions & 0 deletions apps/site/app/routes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { type RouteConfig } from "@react-router/dev/routes";
import { flatRoutes } from "@react-router/fs-routes";

export default flatRoutes() satisfies RouteConfig;
6 changes: 2 additions & 4 deletions apps/site/app/routes/$.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { MetaFunction } from "@remix-run/react/dist/routeModules";
import { type MetaFunction } from "react-router";

import { loader as indexLoader } from "./_index";

Expand All @@ -7,9 +7,7 @@ export { default } from "./_index";
export const loader = indexLoader;

export const meta: MetaFunction<typeof loader> = ({ data }) => [
{
title: data?.title ? `${data.title} - Superflare` : "Superflare",
},
{ title: data?.title ? `${data.title} - Superflare` : "Superflare" },
{
"twitter:title": data?.title ? `${data.title} - Superflare` : "Superflare",
},
Expand Down
16 changes: 7 additions & 9 deletions apps/site/app/routes/_index.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
import {
json,
type LoaderFunctionArgs,
type MetaFunction,
} from "@remix-run/cloudflare";
import { useLoaderData } from "@remix-run/react";
import { type MetaFunction } from "react-router";
import { useLoaderData } from "react-router";
import { Layout } from "~/components/Layout";
import { getManifest, getMarkdownForPath, parseMarkdoc } from "~/docs.server";
import { renderMarkdoc } from "~/markdoc";

import type { Route } from "./+types/_index";

export async function loader({
params,
context: { cloudflare },
}: LoaderFunctionArgs) {
const path = params["*"] ?? ("index" as string);
}: Route.LoaderArgs) {
const path = params["*"] ?? "index";

const useGitHub = process.env.NODE_ENV === "production";
const markdown = await getMarkdownForPath(
Expand All @@ -34,7 +32,7 @@ export async function loader({
const { content, title, tableOfContents, description } =
parseMarkdoc(markdown);

return json({ content, title, tableOfContents, manifest, description });
return { content, title, tableOfContents, manifest, description };
}

export const meta: MetaFunction<typeof loader> = ({ data }) => [
Expand Down
4 changes: 3 additions & 1 deletion apps/site/load-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ type Cloudflare = Omit<PlatformProxy<Env>, "dispose" | "caches"> & {
caches: CacheStorage;
};

declare module "@remix-run/cloudflare" {
declare module "react-router" {
interface AppLoadContext {
cloudflare: Cloudflare;
}
}

export {}; // necessary for TS to treat this as a module
18 changes: 9 additions & 9 deletions apps/site/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,23 @@
"type": "module",
"private": true,
"scripts": {
"build": "remix vite:build",
"build": "react-router build",
"deploy": "wrangler deploy",
"dev:remix": "remix vite:dev",
"dev:remix": "react-router dev",
"dev:docs": "node ./scripts/serve-local-docs.mjs",
"dev": "concurrently \"npm:dev:*\"",
"start": "wrangler dev",
"typegen": "wrangler types",
"typecheck": "tsc"
"typegen": "wrangler types && react-router typegen",
"typecheck": "react-router typegen && tsc"
},
"browserslist": "defaults, not ie <= 11",
"dependencies": {
"@docsearch/css": "^3.8.0",
"@docsearch/react": "^3.8.0",
"@headlessui/react": "^2.1.2",
"@markdoc/markdoc": "0.4.0",
"@remix-run/cloudflare": "^2.12.1",
"@remix-run/react": "^2.12.1",
"@react-router/cloudflare": "^7.0.0",
"@react-router/fs-routes": "^7.0.0",
"@sindresorhus/slugify": "^2.1.1",
"@tailwindcss/typography": "^0.5.8",
"autoprefixer": "^10.4.19",
Expand All @@ -33,13 +33,13 @@
"prism-react-renderer": "^2.3.1",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-router": "^7.0.0",
"tailwindcss": "^3.4.4",
"tiny-invariant": "^1.3.1"
},
"devDependencies": {
"@cloudflare/workers-types": "^4.20241011.0",
"@remix-run/dev": "^2.12.1",
"@remix-run/eslint-config": "^2.12.1",
"@cloudflare/workers-types": "^4.20250109.0",
"@react-router/dev": "^7.0.0",
"@types/js-yaml": "^4.0.5",
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
Expand Down
3 changes: 3 additions & 0 deletions apps/site/react-router.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { type Config } from "@react-router/dev/config";

export default { ssr: true } satisfies Config;
16 changes: 13 additions & 3 deletions apps/site/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
{
"include": ["worker-configuration.d.ts", "**/*.ts", "**/*.tsx"],
"include": [
"worker-configuration.d.ts",
"**/*.ts",
"**/*.tsx",
".react-router/types/**/*"
],
"compilerOptions": {
"lib": ["DOM", "DOM.Iterable", "ES2022"],
"types": ["@remix-run/cloudflare", "vite/client"],
"types": [
"@cloudflare/workers-types",
"@react-router/cloudflare",
"vite/client"
],
"rootDirs": [".", "./.react-router/types"],
"isolatedModules": true,
"esModuleInterop": true,
"jsx": "react-jsx",
Expand All @@ -18,7 +28,7 @@
"~/*": ["./app/*"]
},

// Remix takes care of building everything in `remix build`.
// React router takes care of building everything in `react-router build`.
"noEmit": true
}
}
8 changes: 0 additions & 8 deletions apps/site/types/build.d.ts

This file was deleted.

19 changes: 3 additions & 16 deletions apps/site/vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,10 @@
import { reactRouter } from "@react-router/dev/vite";
import { cloudflareDevProxy } from "@react-router/dev/vite/cloudflare";
import { defineConfig } from "vite";
import {
vitePlugin as remix,
cloudflareDevProxyVitePlugin,
} from "@remix-run/dev";
import tsconfigPaths from "vite-tsconfig-paths";

export default defineConfig({
plugins: [
cloudflareDevProxyVitePlugin(),
remix({
future: {
v3_fetcherPersist: true,
v3_lazyRouteDiscovery: true,
v3_relativeSplatPath: true,
v3_throwAbortReason: true,
},
}),
tsconfigPaths(),
],
plugins: [cloudflareDevProxy(), reactRouter(), tsconfigPaths()],
ssr: {
noExternal: ["@docsearch/react", "@markdoc/markdoc"],
resolve: {
Expand Down
1 change: 1 addition & 0 deletions apps/site/worker-configuration.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ interface Env {
DOCSEARCH_APP_ID: string;
DOCSEARCH_API_KEY: string;
DOCSEARCH_INDEX_NAME: string;
GITHUB_TOKEN: string;
}
8 changes: 4 additions & 4 deletions apps/site/worker.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { createRequestHandler, type ServerBuild } from "@remix-run/cloudflare";
import { createRequestHandler, type ServerBuild } from "react-router";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore This file won’t exist if it hasn’t yet been built
import * as build from "./build/server"; // eslint-disable-line import/no-unresolved

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const handleRemixRequest = createRequestHandler(build as any as ServerBuild);
const handleRequest = createRequestHandler(build as any as ServerBuild);

export default {
async fetch(request, env, ctx) {
Expand All @@ -15,7 +15,7 @@ export default {
// `getPlatformProxy` used during development via Remix's
// `cloudflareDevProxyVitePlugin`:
// https://developers.cloudflare.com/workers/wrangler/api/#getplatformproxy
cf: request.cf,
cf: request.cf!,
ctx: {
passThroughOnException: ctx.passThroughOnException.bind(ctx),
waitUntil: ctx.waitUntil.bind(ctx),
Expand All @@ -24,7 +24,7 @@ export default {
env,
},
};
return await handleRemixRequest(request, loadContext);
return await handleRequest(request, loadContext);
} catch (error) {
console.log(error);
return new Response("An unexpected error occurred", { status: 500 });
Expand Down
2 changes: 1 addition & 1 deletion examples/remix-cms/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/** @type {import('eslint').Linter.Config} */
module.exports = {
extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"],
extends: [],
};
1 change: 1 addition & 0 deletions examples/remix-cms/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ node_modules
.env
/.wrangler
superflare.env.d.ts
.react-router/
2 changes: 1 addition & 1 deletion examples/remix-cms/app/components/admin/Button.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Link } from "@remix-run/react";
import { Link } from "react-router";
import clsx from "clsx";

export function Button({
Expand Down
Loading