···11+# React + TypeScript + Vite
22+33+This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
44+55+Currently, two official plugins are available:
66+77+- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) (or [oxc](https://oxc.rs) when used in [rolldown-vite](https://vite.dev/guide/rolldown)) for Fast Refresh
88+- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
99+1010+## React Compiler
1111+1212+The React Compiler is enabled on this template. See [this documentation](https://react.dev/learn/react-compiler) for more information.
1313+1414+Note: This will impact Vite dev & build performances.
1515+1616+## Expanding the ESLint configuration
1717+1818+If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
1919+2020+```js
2121+export default defineConfig([
2222+ globalIgnores(['dist']),
2323+ {
2424+ files: ['**/*.{ts,tsx}'],
2525+ extends: [
2626+ // Other configs...
2727+2828+ // Remove tseslint.configs.recommended and replace with this
2929+ tseslint.configs.recommendedTypeChecked,
3030+ // Alternatively, use this for stricter rules
3131+ tseslint.configs.strictTypeChecked,
3232+ // Optionally, add this for stylistic rules
3333+ tseslint.configs.stylisticTypeChecked,
3434+3535+ // Other configs...
3636+ ],
3737+ languageOptions: {
3838+ parserOptions: {
3939+ project: ['./tsconfig.node.json', './tsconfig.app.json'],
4040+ tsconfigRootDir: import.meta.dirname,
4141+ },
4242+ // other options...
4343+ },
4444+ },
4545+])
4646+```
4747+4848+You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:
4949+5050+```js
5151+// eslint.config.js
5252+import reactX from 'eslint-plugin-react-x'
5353+import reactDom from 'eslint-plugin-react-dom'
5454+5555+export default defineConfig([
5656+ globalIgnores(['dist']),
5757+ {
5858+ files: ['**/*.{ts,tsx}'],
5959+ extends: [
6060+ // Other configs...
6161+ // Enable lint rules for React
6262+ reactX.configs['recommended-typescript'],
6363+ // Enable lint rules for React DOM
6464+ reactDom.configs.recommended,
6565+ ],
6666+ languageOptions: {
6767+ parserOptions: {
6868+ project: ['./tsconfig.node.json', './tsconfig.app.json'],
6969+ tsconfigRootDir: import.meta.dirname,
7070+ },
7171+ // other options...
7272+ },
7373+ },
7474+])
7575+```
···11+export interface BlogPost {
22+ datePosted: string;
33+ title: string;
44+ content: string;
55+}
66+77+export const posts: BlogPost[] = [
88+ {
99+ datePosted: "2025-11-15",
1010+ title: "My First Blog Post",
1111+ content:
1212+ "This is my first blog post. I am excited to share my thoughts with the world! lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
1313+ },
1414+ {
1515+ datePosted: "2025-11-17",
1616+ title: "My Second Blog Post",
1717+ content:
1818+ "This is my second blog post. I am excited to share my thoughts with the world!",
1919+ },
2020+ {
2121+ datePosted: "2025-11-18",
2222+ title: "My Third Blog Post",
2323+ content:
2424+ "This is my third blog post. I am excited to share my thoughts with the world!",
2525+ },
2626+];
+19
react/src/main.tsx
···11+import { StrictMode } from "react";
22+import { createRoot } from "react-dom/client";
33+import { BrowserRouter, Routes, Route } from "react-router";
44+import "./index.css";
55+import App from "./App.tsx";
66+import { Post, PostLayout } from "./components/Post.tsx";
77+88+createRoot(document.getElementById("root")!).render(
99+ <StrictMode>
1010+ <BrowserRouter>
1111+ <Routes>
1212+ <Route index element={<App />} />
1313+ <Route path="entries" element={<PostLayout />}>
1414+ <Route path=":postId" element={<Post />} />
1515+ </Route>
1616+ </Routes>
1717+ </BrowserRouter>
1818+ </StrictMode>,
1919+);