Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
093dd58
feat(react-router): react router
ScriptedAlchemy Dec 13, 2024
0ccc528
feat(react-router): react router
ScriptedAlchemy Dec 13, 2024
12cc2c2
feat(react-router): react router
ScriptedAlchemy Dec 13, 2024
72c1bf9
feat(react-router): react router
ScriptedAlchemy Dec 13, 2024
73856be
feat(react-router): react router
ScriptedAlchemy Dec 13, 2024
0f91655
feat(plugin-manifest): implement named chunk organization
ScriptedAlchemy Dec 13, 2024
2e6c827
feat(rsbuild-plugin): support async route chunk flush
ScriptedAlchemy Dec 13, 2024
79be5a5
chore(react-router): convert server to mjs
ScriptedAlchemy Dec 13, 2024
e348b2d
chore(react-router): convert server to mjs
ScriptedAlchemy Dec 13, 2024
0bea51b
chore(react-router): convert server to mjs
ScriptedAlchemy Dec 13, 2024
fc0cc8f
chore(react-router): convert server to mjs
ScriptedAlchemy Dec 14, 2024
3e9a816
feat(react-router): enhance SSR support and general configuration in …
ScriptedAlchemy Dec 14, 2024
c33a554
stash
ScriptedAlchemy Dec 14, 2024
4e6be44
chore(react-router): update type definitions and improve SSR handling
ScriptedAlchemy Dec 14, 2024
e94420b
fix(react-router): improve SSR handling and response management
ScriptedAlchemy Dec 14, 2024
b3f3048
chore(react-router): add cspell configuration for improved spell chec…
ScriptedAlchemy Dec 14, 2024
4921130
stash
ScriptedAlchemy Dec 17, 2024
be79012
stash
ScriptedAlchemy Dec 18, 2024
7fd88c9
refactor(react-router): remove deprecated entry files and update paths
ScriptedAlchemy Dec 18, 2024
bd33a02
chore: add templates
ScriptedAlchemy Dec 18, 2024
7708723
feat(react-router): add new loadRouteModule function for improved rou…
ScriptedAlchemy Dec 19, 2024
f318d3c
chore: add templates
ScriptedAlchemy Dec 19, 2024
63f2235
chore: add templates
ScriptedAlchemy Dec 19, 2024
3920ebe
chore: add templates
ScriptedAlchemy Dec 19, 2024
b6cd222
chore: types
ScriptedAlchemy Dec 31, 2024
f1fe394
feat(plugin-react-router): support route conventions
ScriptedAlchemy Jan 29, 2025
f837aa1
fix(plugin-react-router): disable hmr and use live reload
ScriptedAlchemy Jan 29, 2025
1215ee4
refactor(react-router-sample): simplify plugin configuration
ScriptedAlchemy Jan 29, 2025
44145f3
fix(plugin-react-router): get examples working
ScriptedAlchemy Jan 31, 2025
3aba4e9
fix(plugin-react-router): get examples working
ScriptedAlchemy Feb 1, 2025
5be4758
fix(plugin-react-router): get examples working
ScriptedAlchemy Feb 1, 2025
9b95f59
fix(plugin-react-router): builtin node server
ScriptedAlchemy Feb 4, 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
7 changes: 6 additions & 1 deletion biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,12 @@
"*.svelte",
"template-lit-*/src/my-element.*",
"tsconfig.json",
"tsconfig.*.json"
"tsconfig.*.json",
"**/dist/**",
"**/public/js/**",
"**/build/**",
"**/.cache/**",
"**/.temp/**"
],
"ignoreUnknown": true
},
Expand Down
1 change: 1 addition & 0 deletions cspell.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ module.exports = {
'node_modules',
'pnpm-lock.yaml',
'README.pt-BR.md',
'**/public/js/**',
],
flagWords: banWords,
dictionaries: ['dictionary'],
Expand Down
11 changes: 11 additions & 0 deletions examples/react-router/cloudflare/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.DS_Store
/node_modules/
*.tsbuildinfo

# React Router
/.react-router/
/build/

# Cloudflare
.mf
.wrangler
71 changes: 71 additions & 0 deletions examples/react-router/cloudflare/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Welcome to React Router!

A modern, production-ready template for building full-stack React applications using React Router.

## Features

- 🚀 Server-side rendering
- ⚡️ Hot Module Replacement (HMR)
- 📦 Asset bundling and optimization
- 🔄 Data loading and mutations
- 🔒 TypeScript by default
- 🎉 TailwindCSS for styling
- 📖 [React Router docs](https://reactrouter.com/)

## Getting Started

### Installation

Install the dependencies:

```bash
npm install
```

### Development

Start the development server with HMR:

```bash
npm run dev
```

Your application will be available at `http://localhost:5173`.

## Building for Production

Create a production build:

```bash
npm run build
```

## Deployment

Deployment is done using the Wrangler CLI.

To build and deploy directly to production:

```sh
npm run deploy
```

To deploy a preview URL:

```sh
npx wrangler versions upload
```

You can then promote a version to production after verification or roll it out progressively.

```sh
npx wrangler versions deploy
```

## Styling

This template comes with [Tailwind CSS](https://tailwindcss.com/) already configured for a simple default starting experience. You can use whatever CSS framework you prefer.

---

Built with ❤️ using React Router.
15 changes: 15 additions & 0 deletions examples/react-router/cloudflare/app/app.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
@import 'tailwindcss';

@theme {
--font-sans: 'Inter', ui-sans-serif, system-ui, sans-serif,
'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
}

html,
body {
@apply bg-white dark:bg-gray-950;

@media (prefers-color-scheme: dark) {
color-scheme: dark;
}
}
44 changes: 44 additions & 0 deletions examples/react-router/cloudflare/app/entry.server.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { isbot } from 'isbot';
import { renderToReadableStream } from 'react-dom/server';
import type { AppLoadContext, EntryContext } from 'react-router';
import { ServerRouter } from 'react-router';

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

const body = await renderToReadableStream(
<ServerRouter context={routerContext} url={request.url} />,
{
onError(error: unknown) {
// biome-ignore lint: intentional parameter reassignment
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,
});
}
75 changes: 75 additions & 0 deletions examples/react-router/cloudflare/app/root.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import {
Links,
Meta,
Outlet,
Scripts,
ScrollRestoration,
isRouteErrorResponse,
} from 'react-router';

import type { Route } from './+types/root';
import './app.css';

export const links: Route.LinksFunction = () => [
{ rel: 'preconnect', href: 'https://fonts.googleapis.com' },
{
rel: 'preconnect',
href: 'https://fonts.gstatic.com',
crossOrigin: 'anonymous',
},
{
rel: 'stylesheet',
href: 'https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap',
},
];

export function Layout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<Meta />
<Links />
</head>
<body>
{children}
<ScrollRestoration />
<Scripts />
</body>
</html>
);
}

export default function App() {
return <Outlet />;
}

export function ErrorBoundary({ error }: Route.ErrorBoundaryProps) {
let message = 'Oops!';
let details = 'An unexpected error occurred.';
let stack: string | undefined;

if (isRouteErrorResponse(error)) {
message = error.status === 404 ? '404' : 'Error';
details =
error.status === 404
? 'The requested page could not be found.'
: error.statusText || details;
} else if (import.meta.env.DEV && error && error instanceof Error) {
details = error.message;
stack = error.stack;
}

return (
<main className="pt-16 p-4 container mx-auto">
<h1>{message}</h1>
<p>{details}</p>
{stack && (
<pre className="w-full p-4 overflow-x-auto">
<code>{stack}</code>
</pre>
)}
</main>
);
}
3 changes: 3 additions & 0 deletions examples/react-router/cloudflare/app/routes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { type RouteConfig, index } from '@react-router/dev/routes';

export default [index('routes/home.tsx')] satisfies RouteConfig;
17 changes: 17 additions & 0 deletions examples/react-router/cloudflare/app/routes/home.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Welcome } from '../welcome/welcome';
import type { Route } from './+types/home';

export function meta({}: Route.MetaArgs) {
return [
{ title: 'New React Router App' },
{ name: 'description', content: 'Welcome to React Router!' },
];
}

export function loader({ context }: Route.LoaderArgs) {
return { message: context.cloudflare.env.VALUE_FROM_CLOUDFLARE };
}

export default function Home({ loaderData }: Route.ComponentProps) {
return <Welcome message={loaderData.message} />;
}
23 changes: 23 additions & 0 deletions examples/react-router/cloudflare/app/welcome/logo-dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 23 additions & 0 deletions examples/react-router/cloudflare/app/welcome/logo-light.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading