# Host a React (Vite) App on Hostinger Shared Hosting, No VPS Required

URL: https://www.savemores.store/guides/deploy-react-vite-shared-hosting
Author: Mr. Ahmed · Published 2026-10-17 · Updated 2026-10-17 · Website tutorials

## Short answer

- A React app built with Vite is static HTML, JavaScript and CSS, so any Hostinger web hosting plan can serve it without a VPS.
- Upload the contents of `dist`, not the folder itself; `index.html` must sit directly inside `public_html`.
- An `.htaccess` file in Vite's `public` folder rewrites unknown paths to `index.html`, which fixes React Router's 404 on refresh.
- `VITE_` environment variables are baked into the bundle at build time and readable by anyone, so never put secrets in them.
- The same steps work for Vue, Svelte, Astro, plain HTML and Next.js with `output: 'export'`.

## Why shared hosting is enough here

Once Vite has built it, a React app is just HTML, JavaScript and CSS. There is no server code to run, so any [Hostinger web hosting](https://www.savemores.store/hostinger/web-hosting) plan can serve it. Paying for a VPS to host static files is money spent on nothing.

The same process works for Vue, Svelte, Astro, plain HTML and Next.js with `output: 'export'`. If your app needs server rendering, API routes or a database, you need a VPS or a plan with managed Node.js; the [Next.js VPS guide](https://www.savemores.store/vps/deploy-nextjs) covers that path.

## Step 1: build for production

Anything prefixed `VITE_` is written into the bundle at build time. Set the production values before you build, and never put a secret in one, because anyone can read it in the browser.

```bash
npm ci
npm run build
# Output is in ./dist
```

> From the bench: Treat every `VITE_` variable as public, because it is. API keys that must stay private belong on a server you control, not in a static bundle. I would rather say this once too often than see a key scraped from a JavaScript file.

## Step 2: add .htaccess before the build ships

React Router links like `/dashboard` work when clicked but return a 404 on refresh, because Apache goes looking for a real `/dashboard` file. The rewrite below sends every unknown path to `index.html` so the router can take over. It also forces HTTPS and sets cache headers: a year for Vite's hashed assets, and no-cache for `index.html` so new releases are picked up.

Put the file in your project's `public` folder. Vite copies everything in `public` into `dist`, so it ships with every build without you thinking about it.

public/.htaccess

```apache
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /

  # Force HTTPS
  RewriteCond %{HTTPS} !=on
  RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

  # Send unknown paths to the SPA
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.html [L]
</IfModule>

# Vite's hashed assets never change, so cache them for a year
<IfModule mod_headers.c>
  <FilesMatch "\.(js|css|woff2|svg|png|jpg|webp|avif)$">
    Header set Cache-Control "public, max-age=31536000, immutable"
  </FilesMatch>
  <FilesMatch "index\.html$">
    Header set Cache-Control "no-cache"
  </FilesMatch>
</IfModule>
```

> From the bench: Files that start with a dot are hidden on macOS and Linux, which makes them easy to leave behind when you zip or upload. After building, run `ls -a dist` and confirm .htaccess is there.

## Step 3: upload to public_html

Upload what is inside `dist`, not the `dist` folder. `index.html` has to sit directly in `public_html`. Pick whichever method suits you; if hPanel is new to you, the [hPanel tour](https://www.savemores.store/guides/hpanel-tour) shows where everything lives.

- **File Manager**: zip the contents of dist, open hPanel, go to Files, then File Manager, then public_html. Upload the zip, right-click and extract. Delete the default index.php or default.php if there is one.
- **FTP**: create an FTP account in hPanel, connect with FileZilla, and drag the contents of dist into public_html.
- **Automated**: have GitHub Actions build the app and upload dist over FTP on every push, so you never upload by hand.

## Serving from a subfolder instead of the root

If the app lives at `example.com/app/`, tell both Vite and the router about the base path, then adjust the `.htaccess` to match: change `RewriteBase /` to `RewriteBase /app/`, and the last rule to `RewriteRule . /app/index.html [L]`.

vite.config.ts

```ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

export default defineConfig({
  plugins: [react()],
  base: "/app/",
});
```

React Router

```tsx
<BrowserRouter basename="/app">
```

## Step 4: confirm SSL, then verify the deploy

Hostinger includes a free SSL certificate on web hosting plans. Check it is active under the website's Security, then SSL section in hPanel; it is normally installed automatically within a few minutes of adding the domain.

- **Blank page after upload**: the asset paths are wrong, almost always because the app is not at the domain root. Set `base` in vite.config.ts and rebuild. 404s on /assets/ files in the console confirm it.
- **404 when refreshing a route**: .htaccess did not make it into public_html. Check for it with File Manager's hidden-files option.
- **The old version keeps appearing**: you uploaded the dist folder itself, so the new index.html is in public_html/dist rather than public_html.

1. Open the site over https:// and confirm the padlock.
2. Click into a nested route, then refresh the page. You should see the page, not a 404.
3. Open the browser console and check that no files under /assets/ return 404.
4. Deploy a small change and reload. Because index.html is set to no-cache, the new version should appear without clearing your cache.

## FAQ

### Which Hostinger plan should I use for a React app?

Single or Premium web hosting is plenty for one app, because it only serves static files. Premium lets you host more sites and includes a free domain on longer terms.

### Why is my React app a blank page after uploading?

The asset paths are usually wrong. If the app is not at the domain root, set base in vite.config.ts and rebuild; 404 errors on /assets/ files in the browser console confirm the cause.

### Can I run a Node backend alongside the React frontend?

The frontend can live on shared hosting, but the Node API needs a VPS or a plan with managed Node.js. A common split is the React build on web hosting and the API on a small VPS at api.example.com.

### Does WEBHOST2026 work on web hosting?

Yes. The links on this site apply WEBHOST2026 to web hosting plans for an extra 20% off eligible terms.
