Starting a new React project with support for TypeScript, Serverless, and Routing
Follow these steps to start and deploy a new React project right from your localhost with support for TypeScript, serverless, and routing using Vite and Vercel CLI. If you wish to jump start your project without going through these steps, simply clone this repo: https://github.com/smohadjer/boilerplate-react-serverless-vite
mkdir my-project
cd my-project
npm create vite@latest -- --template react-ts .
npm install
npm run dev
Now your react project with TypeScript support is available at: http://localhost:5173/
Adding serverless support
We use Vercel's free serverless platform for running our application. If you don't have Vercel CLI, install it first:
npm i -g vercel
Create an api folder in root and add a test.js file with following content:
// api/test.js
import fs from 'fs';
import path from 'path';
export default async (req, res) => {
const jsonPath = path.join(process.cwd(), 'data', 'data.json');
const jsonFile = fs.readFileSync(jsonPath, 'utf8');
const json = JSON.parse(jsonFile);
res.setHeader('Content-Type', 'application/json');
return res.json(json);
}
Now create a data
folder in root and put a data.json
with following content in it:
[
{
"id": 1,
"name": "Apple"
},
{
"id": 2,
"name": "Banana"
},
{
"id": 3,
"name": "Kiwi"
}
]
Now create Home.tsx file in 'src' folder and paste the following inside:
import { useState, useEffect } from "react";
interface Item {
id: string;
name: string;
}
export function Home() {
const [data, setData] = useState([]);
useEffect(() => {
fetch('/api/json-server')
.then(res => res.json())
.then(json => {
setData(json);
});
}, []);
return (
<ul>
{
data.map((item: Item) => {
return <li key={item.id}>Item {item.id} {item.name}</li>
})
}
</ul>
)
}
Now open src/App.tsx
, remove all content and paste the following instead:
import { Home } from './Home';
export default () => {
return (
<Home />
)
}
Now in terminal run vercel dev
and answer questions asked in cli. Then open http://localhost:3000
and you have to be able to see a list of fruits rendered in your browser. To deploy live run:
vercel --prod
Adding Routing
If you wish to add routing to your project, follow the next steps:
- run
npm i react-router-dom
- open
src/main.tsx
and replace its content with the following:
import React from 'react'
import ReactDOM from 'react-dom/client'
import { BrowserRouter } from "react-router-dom";
import App from './App.tsx'
import './index.css'
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>,
)
- create
src/About.tsx
with following content:
export function About() {
return (
<h1>About</h1>
)
}
- replace content of
src/App.tsx
with the following:
import { Routes, Route } from "react-router-dom";
import { Home } from "./Home";
import { About } from "./About";
export default function App() {
return (
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
);
}
- add a link to about page on the home page by adding the following two changes in
src/Home.tsx
:
...
// import Link
import { Link } from 'react-router-dom';
...
return (
<>
...
{/* using Link component for navigation */}
<p><Link to="/about">About</Link></p>
</>
)
Now if run vercel dev
and go to http://localhost:3000 you will see the homepage and if you click the About link you will go to about page without a page reload from the server.
If you deploy to Vercel you may notice that reloading any page except the index.html will throw a 404 error. To fix this problem we should redirect all page requests to index.html so that react router can then take over the routing task. We do this by adding a rewrite rule for each request to vercel.json
in root of the project:
{
"rewrites": [
{ "source": "/about", "destination": "/" }
{ "source": "/about:path", "destination": "/" }
]
}