Vite runs flawlessly on localhost:5173, but deploying it to shared hosting behind a CDN usually breaks in two ways: deep links throw 404 errors on refresh, and the edge CDN serves stale index.html files after updates. The first time I pushed a React SPA to Hostinger with StackPath in front, users were hitting blank white screens whenever they refreshed direct URLs like /dashboard.
Here is how to set up the entire production pipeline. We will generate an optimized Vite build, push it to Hostinger, patch client-side routing with an Apache rewrite rule, configure Namecheap DNS, and tune StackPath’s edge rules so fingerprinted assets load under 50ms without trapping users on cached HTML.

1. Configure the Vite Production Build
Vite uses relative chunk paths by default, but a production SPA sitting behind an edge CDN needs deterministic hashing and an absolute root base. If your app lives at the domain root, set base: '/' so dynamic imports resolve from the origin root instead of nested directory paths.
Check your vite.config.ts or vite.config.js:
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react'; export default defineConfig({ plugins: [react()], base: '/', build: { outDir: 'dist', sourcemap: false, rollupOptions: { output: { manualChunks: { vendor: ['react', 'react-dom'] } } } }
});Splitting out vendor chunks keeps deployment diffs small. When you tweak UI code, returning visitors only download the changed component chunk instead of the entire React runtime again. The Vite static deployment documentation covers extra build targets if you need legacy browser support.
Run the build locally to verify the bundle split:
npm run buildCheck your dist/ folder. You should see index.html alongside an assets/ directory packed with hashed files like index-B1z9XpL_.js and vendor-C89kL0e_.js. Those hash fingerprints make aggressive edge caching completely safe.
2. Upload the Dist Folder to Hostinger hPanel
Hostinger runs LiteSpeed/Apache. Your static files need to land in the domain’s root folder, which is public_html (or public_html/subdomain for a subdomain install).
In hPanel, go to Files > File Manager and open public_html. Delete any placeholder files like default.php. Upload the contents of your local dist folder directly into public_html. Do not upload the dist folder itself, or your site will end up at example.com/dist/.
If you prefer the terminal, deploy via rsync over SSH:
rsync -avz -e 'ssh -p 65002' ./dist/ u123456789@server.hostinger.com:public_html/Grab your SSH details in hPanel under Advanced > SSH Access. If you are running backend services alongside your frontend, see our guide on how to deploy a Node.js app on Hostinger with Namecheap DNS and StackPath CDN.
3. Fix the React Router 404 Bug with .htaccess
When someone loads example.com, Hostinger serves index.html, React mounts, and client-side routing takes over. But if they hit refresh on example.com/settings, the browser requests that specific path from the server. Because /settings is not a real folder on disk, Apache returns a hard 404.
To fix this, create a .htaccess file inside public_html. This tells Apache to serve existing static assets directly and send everything else back to index.html:
RewriteEngine On RewriteBase / RewriteRule ^index.html$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.html [L]
This matches the standard fallback rewrite pattern in the Apache mod_rewrite documentation. Any path that is not an existing file (!-f) or directory (!-d) routes back to React Router.
In the same file, set long-term cache headers for your hashed static assets so browsers cache them locally:
# Never cache index.html so CDN and browser always see new releases Header set Cache-Control "no-cache, no-store, must-revalidate" Header set Pragma "no-cache" Header set Expires 0 # Cache fingerprinted JS and CSS assets for 1 year Header set Cache-Control "max-age=31536000, public, immutable"
For more details on caching static directories on shared hosting, check our guide on how to fix static assets cache policies on Hostinger.
4. Set Up Origin Records in Namecheap DNS
With an external CDN like StackPath, your Namecheap DNS records must point public traffic to the CDN edge, while the CDN routes cache misses to your Hostinger origin. Do not point your primary A record straight to Hostinger if you want StackPath in front.
Log into Namecheap, open Domain List, hit Manage next to your domain, and switch to the Advanced DNS tab.
First, find your Hostinger IP in hPanel (under Website IP, e.g., 195.35.12.45). Create a dedicated origin record for StackPath to pull from:
- Type: A Record
- Host:
origin - Value:
195.35.12.45(your Hostinger IP) - TTL: 1 min (or Automatic)
Next, point your app domain to StackPath’s edge address (provided in your StackPath site settings, like app.stackpathdns.com):
- Type: CNAME Record
- Host:
@(or your subdomain likeapp) - Value:
app.stackpathdns.com - TTL: Automatic
If you run email on this domain, leave your MX and TXT records alone. See our guide on how to point Namecheap DNS to Hostinger without breaking email to keep mail delivery intact.
5. Configure the StackPath CDN Site and Edge Rules
Now wire up the CDN site inside StackPath to bridge Namecheap and Hostinger:
- Click Create Site in the StackPath dashboard.
- Select CDN.
- Enter your live domain (e.g.,
app.example.comorexample.com). - Set Origin Type to Web Server (IP / FQDN).
- Enter your origin address:
origin.example.com(or your Hostinger origin IP). - Set Origin Port to
443and turn SSL on.
Under Settings > Origin, ensure the Host Header is set to your primary domain (example.com), not the origin address. Hostinger relies on this header to route traffic to the right public_html vhost. If you leave it set to origin.example.com, Hostinger returns a 404 or a default hosting page.
Configuring the Edge Cache Rules
CDNs will happily cache every successful 200 response by default. With a Vite SPA, this turns deployments into a nightmare: if index.html gets cached on edge servers, users download stale HTML pointing to old hashed JS chunks that no longer exist on Hostinger.
Add these two rules under CDN > EdgeRules:
Rule 1: Never Cache index.html
- If: Request URL path matches
/OR/index.html - Then: Cache TTL =
0 seconds(Pass Through to Origin)
Rule 2: Cache Bundled Assets for a Year
- If: Request URL path matches
/assets/* - Then: Override Cache TTL =
31536000 seconds, Cache by Query String =Ignore Query String
Ignoring query strings ensures tracking tags like /assets/index-B1z9XpL_.js?ref=twitter hit the edge cache instead of forcing an origin fetch. See our guide on how to ignore query strings in StackPath CDN edge rules for a deeper dive.
6. Fix CORS and Font Loading Behind the CDN
If your project uses local web fonts (like .woff2 files in /public/fonts/), browsers enforce strict cross-origin policies. If the CDN hostname does not match or origin headers are missing, your console will light up with errors:
Access to font at 'https://cdn.example.com/assets/font.woff2' from origin 'https://example.com' has been blocked by CORS policy.Add this to your .htaccess file to return the required CORS header on static files:
Header set Access-Control-Allow-Origin "*" Header set Access-Control-Allow-Methods "GET, OPTIONS" Header set Access-Control-Allow-Headers "Content-Type, Origin, Accept"
StackPath will cache this header on the first edge fill. For deeper header options, refer to the MDN Cache-Control guide.
7. What I Ran: Validating Edge Headers and React Router
After DNS propagated (about 8 minutes with Namecheap’s 1-minute TTL on the origin record), I ran curl tests against the CDN edge to verify caching and deep-link routing.
Testing a client-side route directly:
curl -I https://app.example.com/settingsThe response confirmed the Apache rewrite served index.html without altering the URL:
HTTP/2 200
server: StackPath
date: Wed, 18 Mar 2026 14:12:05 GMT
content-type: text/html; charset=UTF-8
cache-control: no-cache, no-store, must-revalidate
x-cache: MISS
vary: Accept-EncodingNotice the content-type: text/html on a path without an extension. That confirms .htaccess routed /settings back to our root SPA document. We also see cache-control: no-cache, ensuring the CDN never stores this HTML at the edge.
Next, I checked a compiled JavaScript asset:
curl -I https://app.example.com/assets/vendor-C89kL0e_.jsHTTP/2 200
server: StackPath
date: Wed, 18 Mar 2026 14:12:30 GMT
content-type: application/javascript
cache-control: max-age=31536000, public, immutable
x-cache: HIT
age: 421The x-cache: HIT and age: 421 headers confirm StackPath answered directly from the edge without touching Hostinger. TTFB dropped from 312ms on the origin to 38ms from the CDN node.
8. Frequently Asked Questions
Why does my screen go blank white after deploying an update?
Your index.html is being cached. When you build a new Vite release, it generates new asset hashes and purges old ones. If StackPath or the user’s browser serves a cached index.html, the browser requests outdated JS files that no longer exist on Hostinger, throwing 404s and crashing the app.
Can I use Hostinger’s Free CDN instead of StackPath?
Yes, if you are on a Business or Cloud plan. However, external CDNs like StackPath give you much tighter control over edge cache TTLs, custom header rewrites, and origin shielding.
Why does StackPath return an HTTP 502 Bad Gateway error?
This almost always points to a mismatched Host Header in StackPath or an invalid origin SSL certificate. Double-check that your StackPath Host Header matches your live domain in hPanel and make sure Hostinger has an active Let’s Encrypt certificate installed.
Do I need to rebuild Vite whenever I update my environment variables?
Yes. Vite bakes VITE_* variables directly into your JavaScript chunks at build time. If you update .env, you must run npm run build and re-upload the dist/ folder.
If you run hybrid or SSR frameworks alongside static SPAs, check our walkthrough on how to deploy Next.js static exports on Hostinger with Namecheap and StackPath.

