diff --git a/biome.json b/biome.json index 7cdcf69..0afa445 100644 --- a/biome.json +++ b/biome.json @@ -24,5 +24,8 @@ "enabled": true, "clientKind": "git", "useIgnoreFile": true + }, + "files": { + "ignore": ["packages/web/.react-router/*"] } } diff --git a/bun.lockb b/bun.lockb index d0d030b..dca6365 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/packages/web/.gitignore b/packages/web/.gitignore new file mode 100644 index 0000000..d411622 --- /dev/null +++ b/packages/web/.gitignore @@ -0,0 +1,2 @@ +/.react-router/ +/build/ diff --git a/packages/web/app/app.css b/packages/web/app/app.css new file mode 100644 index 0000000..e69de29 diff --git a/packages/web/app/root.tsx b/packages/web/app/root.tsx new file mode 100644 index 0000000..9fc6636 --- /dev/null +++ b/packages/web/app/root.tsx @@ -0,0 +1,75 @@ +import { + isRouteErrorResponse, + Links, + Meta, + Outlet, + Scripts, + ScrollRestoration, +} 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 ( + + + + + + + + + {children} + + + + + ); +} + +export default function App() { + return ; +} + +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 ( +
+

{message}

+

{details}

+ {stack && ( +
+          {stack}
+        
+ )} +
+ ); +} diff --git a/packages/web/app/routes.ts b/packages/web/app/routes.ts new file mode 100644 index 0000000..102b402 --- /dev/null +++ b/packages/web/app/routes.ts @@ -0,0 +1,3 @@ +import { type RouteConfig, index } from "@react-router/dev/routes"; + +export default [index("routes/home.tsx")] satisfies RouteConfig; diff --git a/packages/web/app/routes/home.tsx b/packages/web/app/routes/home.tsx new file mode 100644 index 0000000..f8f8c05 --- /dev/null +++ b/packages/web/app/routes/home.tsx @@ -0,0 +1,13 @@ +import type { Route } from "./+types/home"; +import { Welcome } from "../welcome/welcome"; + +export function meta(_m: Route.MetaArgs) { + return [ + { title: "New React Router App" }, + { name: "description", content: "Welcome to React Router!" }, + ]; +} + +export default function Home() { + return ; +} diff --git a/packages/web/app/welcome/welcome.tsx b/packages/web/app/welcome/welcome.tsx new file mode 100644 index 0000000..22db177 --- /dev/null +++ b/packages/web/app/welcome/welcome.tsx @@ -0,0 +1,77 @@ +export function Welcome() { + return ( +
+
+
+
Hoo
+
+
+ +
+
+
+ ); +} + +const resources = [ + { + href: "https://reactrouter.com/docs", + text: "React Router Docs", + icon: ( + // biome-ignore lint/a11y/noSvgWithoutTitle: + + + + ), + }, + { + href: "https://rmx.as/discord", + text: "Join Discord", + icon: ( + // biome-ignore lint/a11y/noSvgWithoutTitle: + + + + ), + }, +]; diff --git a/packages/web/package.json b/packages/web/package.json index c5bdd78..ecc47c3 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -1,36 +1,45 @@ { - "name": "TODO-template-web", + "name": "react-router-tdkdbesque", "private": true, "version": "0.0.0", "type": "module", "scripts": { - "dev": "bunx --bun vite", - "build": "tsc -b && vite build", + "dev": "react-router dev", + "build": "react-router build", + "start": "react-router-serve ./build/server/index.js", + "typecheck": "react-router typegen && tsc", "lint": "biome lint . && stylelint **/*.css", "preview": "vite preview", "test": "vitest" }, "dependencies": { - "effect": "=3.14.5", - "react": "=19.1.0", - "react-dom": "=19.1.0", + "@react-router/node": "7.4.1", + "@react-router/serve": "7.4.1", + "effect": "3.14.5", + "isbot": "^5", + "react": "19.1.0", + "react-dom": "19.1.0", "react-hook-form": "7.55.0", - "react-router-dom": "7.4.1", + "react-router": "7.4.1", "vite-plugin-top-level-await": "1.5.0" }, "devDependencies": { "@biomejs/biome": "1.9.4", + "@react-router/dev": "7.4.1", "@types/lodash": "4.17.16", + "@types/node": "22.13.17", "@types/react": "19.1.0", "@types/react-dom": "19.1.1", "@vitejs/plugin-react": "4.3.4", "meow": "13.2.0", + "react-router-devtools": "1.1.8", "stylelint": "16.17.0", "stylelint-config-standard": "37.0.0", "typescript": "5.8.2", "typescript-eslint": "8.29.0", "vite": "6.2.4", "vite-plugin-checker": "0.9.1", + "vite-tsconfig-paths": "5.1.4", "vitest": "3.1.1" } } diff --git a/packages/web/react-router.config.ts b/packages/web/react-router.config.ts new file mode 100644 index 0000000..6ff16f9 --- /dev/null +++ b/packages/web/react-router.config.ts @@ -0,0 +1,7 @@ +import type { Config } from "@react-router/dev/config"; + +export default { + // Config options... + // Server-side render by default, to enable SPA mode set this to `false` + ssr: true, +} satisfies Config; diff --git a/packages/web/src/App.tsx b/packages/web/src/App.tsx deleted file mode 100644 index 4ed09e9..0000000 --- a/packages/web/src/App.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { - createBrowserRouter, - Navigate, - Outlet, - RouterProvider, -} from "react-router-dom"; - -const router = createBrowserRouter([ - { - path: "/", - element: , - children: [ - { - path: "/", - element: , - }, - { - path: "test", - element:

Test

, - }, - ], - }, -]); - -function App() { - return ; -} - -export default App; diff --git a/packages/web/src/index.css b/packages/web/src/index.css deleted file mode 100644 index be4b9d3..0000000 --- a/packages/web/src/index.css +++ /dev/null @@ -1,5 +0,0 @@ -html, -body { - margin: 0; - padding: 0; -} diff --git a/packages/web/src/main.tsx b/packages/web/src/main.tsx deleted file mode 100644 index bb311b2..0000000 --- a/packages/web/src/main.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { StrictMode } from "react"; -import { createRoot } from "react-dom/client"; -import App from "./App.tsx"; -import "./index.css"; - -const root = document.getElementById("root"); - -if (root != null) { - createRoot(root).render( - - - , - ); -} else { - console.error("No #root element found"); -} diff --git a/packages/web/src/requireContext.ts b/packages/web/src/requireContext.ts deleted file mode 100644 index e471762..0000000 --- a/packages/web/src/requireContext.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { useContext } from "react"; - -export function useRequiredContext( - c: React.Context, - error: string, -): T { - const ctx = useContext(c); - if (ctx == null) { - throw new Error(error); - } - return ctx; -} diff --git a/packages/web/tsconfig.json b/packages/web/tsconfig.json index 1673d04..9699591 100644 --- a/packages/web/tsconfig.json +++ b/packages/web/tsconfig.json @@ -1,5 +1,16 @@ { "files": [], "extends": "../../tsconfig.base.json", - "include": ["src"] + "include": ["app"], + "compilerOptions": { + "types": ["vitest/importMeta", "vite/client", "node"], + "rootDirs": [".", "./.react-router/types"], + "baseUrl": ".", + "paths": { + "~/*": ["./app/*"] + }, + "esModuleInterop": true, + "verbatimModuleSyntax": true, + "resolveJsonModule": true + } } diff --git a/packages/web/vite.config.ts b/packages/web/vite.config.ts index 707457b..1981e86 100644 --- a/packages/web/vite.config.ts +++ b/packages/web/vite.config.ts @@ -1,6 +1,7 @@ import { defineConfig } from "vite"; import react from "@vitejs/plugin-react"; import checker from "vite-plugin-checker"; +import { reactRouter } from "@react-router/dev/vite"; // https://vitejs.dev/config/ export default defineConfig({ @@ -8,9 +9,9 @@ export default defineConfig({ checker({ biome: { command: "check", dev: { command: "lint" } }, typescript: true, - stylelint: { lintCommand: "stylelint ./src/**/*.css" }, + stylelint: { lintCommand: "stylelint ./app/**/*.css" }, }), - react(), + reactRouter(), ], server: { fs: { diff --git a/tsconfig.base.json b/tsconfig.base.json index daa6b3a..9e2e521 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -1,9 +1,9 @@ { "compilerOptions": { + "lib": ["ES2022", "DOM", "DOM.Iterable"], "target": "ES2022", "useDefineForClassFields": true, - "lib": ["ES2022", "DOM", "DOM.Iterable"], - "types": ["vitest/importMeta"], + "types": ["vitest/importMeta", "vite/client"], "module": "ESNext", "skipLibCheck": true,