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 22 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 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
f687a23
Remove relation promise union → improve Model type
acusti Jan 22, 2025
e59a15c
Remove defunct build.d.ts files, add GH env var
acusti Jan 17, 2025
16a71ad
📝 Fix typos/grammar in docs and comments
acusti Jan 22, 2025
f95ddac
Remove deprecated @remix-run/eslint-config
acusti Jan 17, 2025
1296744
Migrate examples/remix-cms to RR v7
acusti Jan 17, 2025
9f1c860
Migrate templates/remix to RR v7
acusti Jan 17, 2025
89363ac
Migrate apps/site to RR v7
acusti Jan 17, 2025
feca84b
Update lock file with RR v7 dependency changes
acusti Jan 17, 2025
d63b444
Upgrade @cloudflare/workers-types + tsup
acusti Jan 19, 2025
baca18b
Adapt superflare from remix → react-router
acusti Jan 20, 2025
26f6d1c
:memo: Update docs from remix → react-router
acusti Jan 20, 2025
06a2ab3
Update unused pages function example to latest API
acusti Jan 21, 2025
bc55eee
Add react-router to typegen command
acusti Jan 22, 2025
eda1ad7
Migrate docs site/remix-cms/template to RR types
acusti Jan 22, 2025
37d05e5
Return seed callback to enable awaiting result
acusti Jan 22, 2025
61651bb
Bump eslint(-register) dependencies
acusti Jan 27, 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
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
17 changes: 17 additions & 0 deletions apps/site/app/entry.client.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* By default, Remix will handle hydrating your app on the client 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.client
*/
import { startTransition, StrictMode } from "react";
import { hydrateRoot } from "react-dom/client";
import { HydratedRouter } from "react-router/dom";

startTransition(() => {
hydrateRoot(
document,
<StrictMode>
<HydratedRouter />
</StrictMode>
);
});
43 changes: 43 additions & 0 deletions apps/site/app/entry.server.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* 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,
reactRouterContext: EntryContext,
_loadContext: AppLoadContext
) {
const body = await renderToReadableStream(
<ServerRouter context={reactRouterContext} url={request.url} />,
{
onError(error: unknown) {
// Log streaming rendering errors from inside the shell
console.error(error);
responseStatusCode = 500;
},
signal: request.signal,
}
);

if (isbot(request.headers.get("user-agent") || "")) {
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