Deploy a Vite React SPA to Vercel
Deploy a Vite React app with Vercel previews and working SPA deep links.
Introduction
30 Second Summary
You will put your existing app online with a public link anyone can open. Each update can reach a safe test version before it reaches your live app.
In this project, you will connect your existing Vite React app on GitHub to Vercel. You will diagnose a nested-route failure through a preview deployment before releasing the fix through a production deployment.
What You'll Build
You will open your app from a public Vercel URL, test a routing fix on an isolated branch preview, then watch the verified update reach production.
By the end of this project, you'll have:
- A live production app whose homepage loads over HTTPS from a public Vercel URL.
- A branch preview workflow that gives your proposed fix a separate deployment URL.
- Reliable nested routes that remain visible when you open their URLs directly or refresh them.
- Secret Mission: An optional challenge to push your deployment skills further.
Are there any prerequisites?
You need an existing Vite React single-page application with at least one nested client-side route in a personal GitHub repository.
You also need Git, Node.js, npm, VS Code, plus a Vercel account ready on your Mac.
Before We Start
Before the hands-on work begins, choose the existing app you want to deploy. Locking in why you want it online gives each deployment check a meaningful target.
Check Your Production Build
Your existing Vite React app must produce a successful local build before it can go online. A deployment cannot rescue a broken build.
You will check the existing lockfile before building the app. This proves the repository can create its static production files.
You will also confirm that Git points to your personal GitHub repository. This keeps the upcoming deployment connected to the correct source.
In this step, get ready to:
- Open your existing project folder in VS Code.
- Create the production build from the existing npm script.
- Confirm the repository points to your personal GitHub repository.
Open your project in VS Code
The integrated terminal runs commands from the folder currently open in VS Code. Opening the correct folder keeps the build output inside your existing project.
- Press Cmd+Space to open Spotlight on your Mac.
- Type VS Code into Spotlight.
- Press Enter to open VS Code.
- Click File in the menu bar.
- Select Open Folder.
- Select the folder containing your existing Vite React app.
- Click Open.
- Select New Terminal from the Terminal menu.
The integrated terminal appears at the bottom of VS Code. Its prompt shows that commands will run inside your existing project folder.
Build the production files
The package-lock.json file records the dependency versions used by the project. The existing build script uses those installed dependencies to create deployable files.
- Locate package-lock.json in the VS Code Explorer sidebar.
The lockfile should appear alongside the other top-level project files.
- Predict whether the build will finish successfully based on the app you selected.
- Build the app from the integrated terminal by running this command:
npm run build
What Does This Command Do?
- The command runs the existing production build script from your project.
- Vite prepares optimized static files for deployment.
- The completed build places its output in dist.
- Confirm that the terminal completes without a build error.
- Confirm that dist appears in the VS Code Explorer sidebar.
The successful terminal result proves the app can produce its production files. The new dist directory contains that output.
Build Not Completing?
Confirm that the terminal prompt is inside the folder containing package-lock.json. A build error can also identify a problem already present in the existing app.
Ask for help interpreting the build output without changing dependency versions: Help me diagnose my Vite production build error.
Confirm the GitHub remote
A Git remote records where the local repository sends its commits. The remote should identify the personal GitHub repository you plan to connect to the deployment.
- Predict which personal GitHub repository the remote output should identify.
- Display the configured Git remotes by running this command:
git remote -v
What Does This Command Show?
- The command lists the repository's configured remotes.
- The output shows the destination used for fetching commits.
- The output also shows the destination used for pushing commits.
The output should point to the personal GitHub repository containing this app. This confirms that your local build matches the repository you will deploy.
Remote Missing or Unexpected?
Check the account name and repository name shown in the output. Stop here if they identify a different repository.
Use this prompt to review the output safely: Help me understand my Git remote output.
Your app now has a verified production build and the correct repository connection. Next, you will connect that repository to Vercel and open the app from a live production URL.
Deploy Your App to Production
Your React app already produces a clean production build. Now you'll turn that local proof into a public production deployment through Vercel.
A real production URL is the fastest visible win. Vercel can detect a conventional Vite project from GitHub automatically.
In this step, get ready to:
- Connect your personal GitHub repository to a Vercel project.
- Retain the detected Vite root directory plus build settings.
- Open your homepage from a public HTTPS production URL.
Import your repository
A Git integration connects your repository history to Vercel. The dashboard uses this connection to build your app.
- Go to the Vercel dashboard in your browser.
- Sign in to your Vercel account.
- Select New Project.
- Select your personal GitHub repository from the repository list.
- Import the selected repository into the project configuration.
The project configuration screen now shows the settings Vercel detected from your repository.
Why Use Git Integration?
Git integration keeps each deployment connected to the repository change that produced it. This makes your deployment history traceable.
A manual command path can deploy the app. The Git workflow fits the release process you will use throughout this project.
Keep the detected Vite settings
Framework detection lets Vercel choose build defaults from the repository structure. A conventional Vite project usually needs no manual configuration.
- Confirm the detected framework is Vite.
- Confirm the detected root directory points to the folder containing package-lock.json.
These values show that Vercel found the app in the expected repository location.
- Leave the detected build settings unchanged.
- Leave the detected output settings unchanged.
The retained settings match the same Vite project that produced your local build successfully.
Deploy and verify the homepage
Vercel now has the repository plus the settings needed to build it. The next deployment turns that configuration into a public URL.
- Select Deploy.
- Wait for the production deployment to complete.
Before you open the production URL, what do you expect the browser to show?
- Open the production URL from the completed deployment.
Your app's homepage loads from a public Vercel URL over HTTPS. This confirms the first production deployment works.
Homepage Not Loading?
- Confirm that you imported the same personal GitHub repository that passed the local production build.
- Return to the project configuration if the detected root directory points outside the folder containing package-lock.json.
- Use help me diagnose why my Vercel production deployment does not load my Vite homepage for guided troubleshooting.
Your app is live at its production URL. Next, you'll test whether a nested route survives a direct browser request.
Test a Direct Nested Route
Your React app is live at its Vercel production URL. Now you need to test more than the homepage.
Client-side routing can make nested pages look healthy after the app has loaded. A direct request tests whether the host can serve that same path on its own.
In this step, get ready to:
- Visit an existing nested route from the production homepage.
- Request the same route directly in a private browser window.
- Document the direct-load failure against the working homepage.
Navigate to a nested route
The first request stays inside the app that your browser already loaded. This gives you a baseline for the nested route.
- Return to the production homepage from earlier.
- Use your app's navigation to visit an existing nested route.
- Copy the full nested route URL from the browser address bar.
Your existing nested page appears correctly. The address bar now contains its full production URL.
Load the route directly
A private window gives you a fresh browser session. Loading the copied URL there sends the nested path directly to the host.
- Predict whether the direct request will show the nested page or a hosting response.
- Create a new private browser window using your browser's main menu.
- Paste the copied nested route URL into the address bar.
- Press Enter to load the URL directly.
Vercel returns its not-found response instead of the nested React page. This failure is the intended result of the test.
What Did This Prove?
In-app navigation lets React handle the route after the homepage assets have loaded.
A direct load sends the nested path to Vercel first. The not-found response proves that the host cannot currently serve the app from that path.
Confirm the homepage still works
The homepage acts as your control check. It confirms that the deployment is healthy while the nested route request fails.
- Predict whether the production homepage will still load.
- Return to the original browser window from earlier.
- Enter the production homepage URL in the address bar.
- Press Enter to load the homepage directly.
The production homepage loads successfully. You have isolated the failure to direct requests for nested routes.
You have reproduced the routing gap without changing production. Next, you'll test a safe correction away from the live site.
Fix Deep Links in a Preview
Your production test exposed the hosting gap behind the failed direct request. The homepage still loads because it has a matching server entry point.
A Vercel rewrite sends every app path to index.html. An isolated Git branch keeps production unchanged while you verify the fix.
In this step, get ready to:
- Create an isolated branch for the routing fix.
- Add the root-level vercel.json rewrite.
- Prove the preview can handle direct visits to the nested route.
Create the fix branch and rewrite
The branch gives your fix its own Git reference. This lets Vercel build a separate preview without changing the production deployment.
- Create the isolated branch in the integrated terminal from earlier by running this command:
git switch -c fix-spa-deep-links
What does this command do?
- The -c flag creates a new branch named fix-spa-deep-links.
- Git switches your repository to the new branch immediately.
The terminal confirms that your repository is now using the new branch.
- In the VS Code Explorer sidebar, select the folder that contains package-lock.json.
- Click the New File icon in the Explorer toolbar.
- Enter vercel.json as the file name.
- Add the rewrite configuration to vercel.json by pasting this code:
{
"rewrites": [{ "source": "/(.*)", "destination": "/index.html" }]
}
What does this configuration do?
- The rewrites array defines how Vercel handles incoming paths.
- The source pattern matches every requested path.
- The destination serves index.html so the client router can choose the correct screen.
- Save vercel.json.
- Confirm vercel.json appears beside package-lock.json in the Explorer sidebar.
Can't find the configuration file?
Make sure vercel.json sits in the same top-level folder as package-lock.json. A file inside src will not configure the deployment.
Check that the file ends with .json. Help me check where vercel.json belongs in my Vite project.
✔️ Awesome, I've got everything!
Great. Double-check that you saved vercel.json.
ⓧ I'd like to double check the full code
{
"rewrites": [{ "source": "/(.*)", "destination": "/index.html" }]
}
Commit and push the fix
Vercel creates previews from pushed non-production branches. Publishing this commit gives the platform a precise version to build.
- Stage the configuration, commit it, and push the branch by running these commands:
git add vercel.json
git commit -m "Fix SPA deep links on Vercel"
git push -u origin fix-spa-deep-links
What do these commands do?
- The first command stages the current contents of vercel.json.
- The second command records the staged rewrite with the required message.
- The final command publishes fix-spa-deep-links to origin. It also sets the branch's upstream reference.
The terminal confirms that the commit was created. It also confirms that the branch was published to your personal repository.
Branch push not completing?
Confirm that the integrated terminal is still inside your app folder. Check that vercel.json was saved before you staged it.
If Git asks you to authenticate, complete the sign-in flow for your personal repository. Help me troubleshoot this branch push.
Open and verify the preview deployment
A pull request connects your branch fix to the release workflow. GitHub shows the exact configuration change before it reaches the production branch.
- Go to your personal GitHub repository in your browser.
- Select the fix-spa-deep-links branch.
- Click Compare & pull request.
- Confirm the base is your production branch.
- Confirm the compare branch is fix-spa-deep-links.
- Click Create Pull Request.
The pull request now shows the new vercel.json file as its change.
The branch push triggers an isolated preview deployment. Its URL lets you test the routing behavior without replacing production.
- Switch back to the Vercel dashboard from earlier.
- Select your connected project.
- Open Deployments.
- Select the completed preview deployment for fix-spa-deep-links.
Before you test it, predict whether the direct request will render the route or return the previous response.
- Open the preview deployment's homepage.
- Navigate inside the app to the same nested route you tested in production.
- Copy the full preview URL from the browser address bar.
- Open a new private browser window using your browser's menu.
- Paste the preview URL into the address bar.
- Press Enter to load the route directly.
The React route appears instead of the previous not-found response. The rewrite has handed the request to your app.
- Refresh the nested route in the private browser window.
The same route remains visible after the refresh. Your preview has passed the deep-link test.
Still seeing the not-found response?
Confirm that you opened the preview deployment for fix-spa-deep-links. The production deployment still contains the failing version.
Check that the preview completed after your latest branch push. Help me diagnose this preview routing failure.
Your routing fix now works in an isolated preview. Next, you will merge the tested commit so Vercel can release it to production.
Release the Routing Fix
Your Vercel preview deployment has proved that the rewrite keeps your nested React route available during direct visits and refreshes.
The tested commit now needs to reach the production branch. Merging the pull request lets Vercel turn that exact change into a production deployment.
In this step, get ready to:
- Review the tested rewrite in the GitHub pull request.
- Merge the pull request into the production branch.
- Verify the homepage and nested route against the updated production URL.
Review the tested change
The successful preview proves the behavior. The pull request diff confirms that production receives only the change you tested.
- Return to the pull request from the previous step.
- Review its diff against the production branch.
- Confirm that the diff contains the root-level vercel.json rewrite.
The pull request should contain the rewrite that already passed your preview checks.
- Use this checkpoint to compare the complete configuration file:
✔️ The Rewrite Matches
Your pull request contains the same tested rewrite. You are ready to merge it.
ⓧ I'd Like to Double Check
{
"rewrites": [{ "source": "/(.*)", "destination": "/index.html" }]
}
What Does This Configuration Do?
The rewrite serves index.html for matching requests. This gives the client-side router a chance to render the requested nested route.
Merge the pull request
A preview deployment stays isolated from production. Merging the tested pull request moves the same commit into the production release workflow.
- Return to the GitHub pull request from earlier.
- Use its merge control to merge the pull request into the production branch.
- Switch back to the Vercel dashboard from earlier.
- Select Deployments in the project navigation.
- Find the production deployment associated with the merge.
- Wait until the deployment shows a completed status.
The completed production deployment confirms that Vercel built the merged commit from your production branch.
Deployment Not Appearing?
Confirm that the pull request was merged into the production branch configured for your Vercel project.
If the deployment remains missing, help me trace why my merged pull request did not create a Vercel production deployment.
Verify production routes
The production deployment must pass the same checks as the preview. This proves that the verified rewrite is now serving real visitors.
- Predict whether the production homepage and nested route will both survive a direct visit.
- Return to the production homepage in your private browser window.
The homepage should load successfully over HTTPS.
- Open a new private browser window.
- Paste the recorded production URL for the nested route into the address bar.
- Load the URL directly.
The expected React route should appear instead of Vercel's not-found response.
- Refresh the nested route.
The same nested route should remain visible after the refresh. Your routing fix is now live in production.
Route Still Returning Not Found?
Confirm that the completed deployment is marked as a production deployment for the merge. Check that its pull request diff includes the root-level vercel.json file.
If the homepage works but the nested route still fails, help me diagnose why my Vercel production deployment is not applying the SPA rewrite.
Secret mission
Rebuild a Historical Git Reference
Rebuild a pre-fix commit as a separate targeted deployment. You will inspect an older state while keeping the fixed production deployment active.
Clean Up Your Resources
Clean Up Your Resources
Decide whether to keep your resources running, pause them to come back later, or delete them entirely. The Vercel Hobby plan is $0/mo. for personal, non-commercial use within included usage limits.
Resources you used:
- A Vercel project connected to your personal GitHub repository.
- A completed production deployment for the current production branch.
- A completed preview deployment for the routing fix branch.
- A separate historical deployment targeted at the chosen pre-fix commit.
Keep everything running
No action is needed while you are actively building. Future branch pushes continue creating preview deployments.
- Leave the Vercel project connected to your personal GitHub repository.
- Keep vercel.json in the production branch so direct visits to nested routes keep working.
Pause - I'll come back to this later
Pausing delivery preserves the Vercel project for your return. You can resume it from the same section later.
- Open Settings in your Vercel project.
- Stay on the General page.
- Find the Pause Project section.
- Select Pause Project.
The project is now paused while its configuration remains available.
Delete - I don't want to use this again
You can disconnect Git delivery while retaining the project. Complete removal deletes the Vercel project with its deployments.
For disconnection only:
- Open Settings in your Vercel project.
- Select Git.
- Find Connected Git Repository.
- Select Disconnect.
This stops Git-triggered deployments while retaining the Vercel project.
For complete removal:
- Return to Settings in your Vercel project.
- Select General.
- Find the Delete Project section.
- Select Delete.
- Complete the confirmation dialog.
Deleting the project removes its production, preview, and historical deployments.
Nice Work!
Nice Work!
Nice work! You deployed your Vite React SPA to Vercel through a Git-based CI/CD workflow. Its nested routes now load directly in production.
You've learned how to:
- Deploy an existing Vite React app from a personal GitHub repository to a public production URL.
- Diagnose a client-side routing failure by comparing in-app navigation with a direct nested-route request.
- Test an SPA rewrite in an isolated preview deployment. Release the verified fix through a pull request.
- Secret Mission: Rebuild a historical Git commit as a separate deployment without changing production.
Ready to quiz yourself?