Netlify Vue 404 Fix
April 10, 2025 · AI Conversations
### ✅ Solution: Add `_redirects` file
Create a file named `_redirects` in your Vue project’s **`public/`** folder (this is important—it must be in the folder that gets copied into `dist` or `build`).
Inside `_redirects`, add this line:
/* /index.html 200
### 📂 Full Steps:
1. **Create `_redirects` file**
– Path: `public/_redirects`
– Content:
/* /index.html 200
2. **Rebuild and redeploy**
– Rebuild your Vue app (`yarn build` or `npm run build`)
– Deploy to Netlify
3. **Test**
– Navigate to an inner route like `/about`
– Refresh the page—should now work correctly
—
Let me know if you're using a different router mode like `hash` or if you want to switch to it instead (as an alternative workaround).
—
### ✅ Problem Summary
Vue.js uses client-side routing. When you refresh a route like `/about`, Netlify tries to look for an actual `/about` file or folder on the server — it doesn't find one, so it shows a 404.
—
### 🔧 Solution: Create `_redirects` file to handle client-side routing
—
### ✅ Step-by-Step Instructions
#### **1. Ensure Vue Router is in history mode**
In your `src/router/index.js` (or `router.js`):
import { createRouter, createWebHistory } from 'vue-router';
const router = createRouter({
history: createWebHistory(), // <-- history mode
routes: [
{ path: '/', component: () => import('../views/Home.vue') },
{ path: '/about', component: () => import('../views/About.vue') },
// add your other routes here
],
});
export default router;
—
#### **2. Create `_redirects` file**
Create a file named `_redirects` (no file extension) inside the `public/` folder of your Vue project.
**Path**: `public/_redirects`
**Content**:
/* /index.html 200
This tells Netlify: “For any route that’s not a real file, serve `index.html` instead.”
> 📝 The `public/` folder contents are copied to the root of your `dist/` folder on build, so this will work after deployment.
—
#### **3. Build your Vue project**
Run the build command (depending on your setup):
yarn build
# or
npm run build
This will generate a `dist/` folder (or `build/` depending on your config).
—
#### **4. Deploy to Netlify**
– Go to [https://app.netlify.com](https://app.netlify.com)
– Click **"Add new site" > "Import an existing project"**
– Connect your GitHub repo (if you're using Git)
– Or drag and drop your `dist/` folder in the Netlify UI (if you're using manual deploy)
Make sure the **build settings** are correct:
– **Build command**: `npm run build` or `yarn build`
– **Publish directory**: `dist`
—
#### ✅ 5. Test your site
– Navigate to `/about` or any inner route
– Refresh the page
**It should no longer show a 404!**
—
### 💡 Optional: Debugging Tips
If it’s still not working:
– Double-check `_redirects` file has **no extension**
– Confirm it exists in the **`dist/`** folder after build
– In Netlify UI: Go to **Deploys > "Deploy Preview" > Browse deploy folder**, and check for `_redirects`
—
Let me know if you’re using Vite or Vue CLI — steps are similar but build folders and commands might differ slightly.
import NProgress from 'nprogress';
import 'nprogress/nprogress.css';
NProgress.configure({ showSpinner: false, speed: 500, minimum: 0.2 });
import DefaultVuetify from '@/layouts/DefaultVuetify.vue';
import HomeView from '../views/HomeView.vue'
import Youtubeiew from '@/views/Youtubeiew.vue'
import NewsView from '@/views/NewsView.vue'
import LoginView from '@/views/LoginView.vue'
import RegisterView from '@/views/RegisterView.vue'
import DashboardView from '@/views/User/DashboardView.vue'
import ProfileView from '@/views/User/ProfileView.vue'
import SettingsView from '@/views/User/SettingsView.vue'
import ForgetPasswordView from '@/views/ForgetPasswordView.vue'
import PortfolioPage from '@/views/PortfolioPage.vue'
import MainRoutes from './MainRoutes';
import PublicRoutes from './PublicRoutes';
import { useAuthStore } from '@/stores/auth';
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/',
name: 'Frontsite',
component: DefaultVuetify,
children: [
{
path: '/',
name: 'home',
component: PortfolioPage,
},
{
path: '/news',
name: 'news',
component: NewsView,
},
{
path: '/youtube',
name: 'youtube',
component: Youtubeiew,
},
{
name: 'portfolio',
path: '/portfolio',
component:PortfolioPage
},
]
},
// {
// path: '/about',
// name: 'about',
// // route level code-splitting
// // this generates a separate chunk (About.[hash].js) for this route
// // which is lazy-loaded when the route is visited.
// component: () => import('../views/AboutView.vue'),
// },
// {
// path: '/profile',
// name: 'profile',
// component: ProfileView,
// meta: { requiresAuth: true },
// },
// {
// path: '/settings',
// name: 'settings',
// component: SettingsView,
// meta: { requiresAuth: true },
// },
PublicRoutes,
MainRoutes,
],
})
router.beforeEach((to, from, next) => {
const authStore = useAuthStore();
NProgress.start();
if (to.meta.requiresAuth && !authStore.token) {
next('/login'); // Redirect if not logged in
} else {
next();
}
});
router.afterEach(() => {
NProgress.done();
});
export default router
Since you’re using **Vite + Vue 3 + Vue Router in history mode**, here’s the full integration for fixing the **404 on page refresh in Netlify**.
—
## ✅ Full Working Setup for Netlify + Vite + Vue 3 Router (history mode)
### ✅ Step 1: Add `_redirects` file in `public/` folder
#### Path:
/public/_redirects
#### Content:
/* /index.html 200
> This ensures that Netlify routes everything through `index.html`, so Vue Router can handle it.
—
### ✅ Step 2: Double check router history mode
In your `router.js` (which you already have):
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
...
});
✅ You’ve already got this set correctly.
—
### ✅ Step 3: Build the project
From your terminal in the root of your Vue project:
yarn build
# or
npm run build
This will generate a `/dist` folder that includes your app's compiled files.
—
### ✅ Step 4: Deploy to Netlify
#### Option 1: Drag & Drop
– Drag the `/dist` folder into the Netlify dashboard (at https://app.netlify.com)
#### Option 2: Continuous Deployment from Git
If you’re using GitHub or GitLab:
– Connect your repository
– Set build settings:
– **Build Command**: `npm run build` or `yarn build`
– **Publish Directory**: `dist`
—
### ✅ Step 5: Test inner route
– Go to `/news`, `/youtube`, or `/portfolio`
– Refresh the page
You should **no longer see a 404 error**.
—
### ✅ Optional: Preview the output
After running `yarn build`, make sure your `_redirects` file is present in the `/dist` folder:
cat dist/_redirects
It should show:
/* /index.html 200
If it’s missing, check that you placed the `_redirects` file in the **`public/`** folder—not `src/`.
—
Let me know if you’re using a custom domain or you want to add fallback 404 page as well.
6:31:26 PM: yarn run v1.22.22
6:31:26 PM: $ vite build
6:31:26 PM: /bin/sh: 1: vite: not found
6:31:26 PM: error Command failed with exit code 127. (https://ntl.fyi/exit-code-127)
6:31:26 PM: info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
6:31:26 PM:
6:31:26 PM: "build.command" failed
6:31:26 PM: ────────────────────────────────────────────────────────────────
6:31:26 PM:
6:31:26 PM: Error message
6:31:26 PM: Command failed with exit code 127: yarn build (https://ntl.fyi/exit-code-127)
6:31:26 PM:
6:31:26 PM: Error location
6:31:26 PM: In Build command from Netlify app:
6:31:26 PM: yarn build
6:31:26 PM:
6:31:26 PM: Resolved config
6:31:26 PM: build:
6:31:26 PM: base: /opt/build/repo/dist
6:31:26 PM: command: yarn build
6:31:26 PM: commandOrigin: ui
6:31:26 PM: publish: /opt/build/repo/dist
6:31:26 PM: publishOrigin: ui
6:31:26 PM: redirects:
6:31:26 PM: – from: /*
status: 200
to: /index.html
6:31:26 PM: Build failed due to a user error: Build script returned non-zero exit code: 2
6:31:26 PM: Failing build: Failed to build site
6:31:27 PM: Finished processing build request in 14.442s
/bin/sh: 1: vite: not found
means that **Netlify can't find Vite installed** in your environment during build. This usually happens when:
1. You didn’t commit your `package.json` and `yarn.lock` properly.
2. `vite` is not listed as a dependency in your `package.json`.
3. You didn’t set the correct **Build Environment**.
—
### ✅ Fix Steps
#### ✅ 1. Ensure Vite is in your `devDependencies`
Open your `package.json` and check for something like this:
"devDependencies": {
"vite": "^4.5.0", // or any version
...
}
If it’s missing, install it:
yarn add vite --dev
—
#### ✅ 2. Make sure `vite` is in `scripts`
Your `package.json` should have:
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
}
If missing, add those lines under `"scripts"`.
—
#### ✅ 3. Commit all changes to Git
Run:
git add .
git commit -m "Fix: Add vite dependency and build script"
git push
—
#### ✅ 4. Set correct **Build command** and **Publish directory** in Netlify
Go to Netlify Dashboard → Your Site → **Site Settings** → **Build & Deploy** → **Build Settings**
Set:
– **Build command**: `yarn build`
– **Publish directory**: `dist`
—
#### ✅ 5. Redeploy the site
Now trigger a new deploy:
– Manually: go to Netlify → Deploys → "Trigger deploy"
– Or push a new commit to GitHub
—
Let me know if you’re using `pnpm` or `npm` instead of `yarn`, or if you want to switch from `yarn` to `npm`.
—
### ✅ Step-by-Step Debug Checklist
#### ✅ 1. Make sure `_redirects` file is in the **`public/`** folder
Your folder structure should look like:
/project-root
├── public
│ └── _redirects ✅ <- here (not in src/)
├── src
├── dist
├── package.json
> ❗️The `_redirects` file **must be in `public/`**, not in the root or `src/`.
—
#### ✅ 2. Confirm `_redirects` is copied into `dist/` after build
Run:
yarn build
Then check:
cat dist/_redirects
It should output:
/* /index.html 200
If it’s not there, Netlify won’t use it. Try adding it again in `public/`.
—
#### ✅ 3. Correct content of `_redirects`
Ensure the content is **exactly**:
/* /index.html 200
✅ Use **single spaces** — not tabs or extra spacing.
—
#### ✅ 4. Check router mode
Your router is correct:
createWebHistory(import.meta.env.BASE_URL)
✅ But make sure in `vite.config.js`:
export default defineConfig({
base: '/',
...
});
If your project is under a subfolder like `/my-app/`, then use:
base: '/my-app/',
> This must match the Netlify site subpath if you're not deploying at root.
—
#### ✅ 5. Netlify Build Settings
In **Netlify → Site settings → Build & Deploy → Build Settings**, check:
– **Build command**: `yarn build`
– **Publish directory**: `dist`
If `_redirects` is missing from the `dist/` folder at this point, Netlify won’t be able to do client-side routing fallback.
—
#### ✅ 6. Force a full redeploy
Sometimes, Netlify caches your deploy. Trigger a fresh build:
– Go to **Deploys**
– Click **"Trigger deploy" → "Clear cache and deploy site"**
—
### 🧪 Final Test
1. Go to your site.
2. Navigate to `/news` or any nested route.
3. Refresh the page.
It should no longer give you a 404.
—
### Still not working?
Let me know:
– What's the **public URL** or **custom domain** (I can check the headers)?
– Are you deploying via Git or drag-and-drop?
– Can you confirm `_redirects` exists inside `dist/`?
I'll help troubleshoot further.
6:38:27 PM: error Command failed with exit code 127. (https://ntl.fyi/exit-code-127)
6:38:27 PM: info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
6:38:28 PM:
6:38:28 PM: "build.command" failed
6:38:28 PM: ────────────────────────────────────────────────────────────────
6:38:28 PM:
6:38:28 PM: Error message
6:38:28 PM: Command failed with exit code 127: yarn build (https://ntl.fyi/exit-code-127)
6:38:28 PM:
6:38:28 PM: Error location
6:38:28 PM: In Build command from Netlify app:
6:38:28 PM: yarn build
6:38:28 PM:
6:38:28 PM: Resolved config
6:38:28 PM: build:
6:38:28 PM: base: /opt/build/repo/dist
6:38:28 PM: command: yarn build
6:38:28 PM: commandOrigin: ui
6:38:28 PM: publish: /opt/build/repo/dist
6:38:28 PM: publishOrigin: ui
6:38:28 PM: redirects:
6:38:28 PM: – from: /*
status: 200
to: /index.html
6:38:28 PM: Build failed due to a user error: Build script returned non-zero exit code: 2
6:38:28 PM: Failing build: Failed to build site
6:38:28 PM: Finished processing build request in 13.985s
6:38:28 PM: Failed during stage 'building site': Build script returned non-zero exit code: 2 (https://ntl.fyi/exit-code-2)
/bin/sh: 1: vite: not found
means that **Vite is not installed in your project**, or it is not listed properly in your `package.json`.
Let’s fully fix this 🔧.
—
## ✅ Step-by-Step Fix for `vite: not found` on Netlify
### ✅ 1. Check that Vite is listed in `devDependencies`
Open your `package.json`. You **must** have Vite listed like this:
"devDependencies": {
"vite": "^4.0.0", // or any version
...
}
If it's missing, run:
yarn add -D vite
Or with npm:
npm install -D vite
—
### ✅ 2. Check your build script in `package.json`
Under `"scripts"` in `package.json`, you should have:
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
}
If `"build"` is not `vite build`, Netlify won’t know what to do.
—
### ✅ 3. Commit your `package.json` and `yarn.lock`
git add package.json yarn.lock
git commit -m "fix: add vite for Netlify build"
git push
> Netlify installs packages based on your `package.json`. If Vite isn’t listed and committed, it won’t be installed.
—
### ✅ 4. Set correct Netlify build settings
In **Netlify Dashboard → Site Settings → Build & Deploy**:
– **Build Command**: `yarn build`
– **Publish directory**: `dist`
Also confirm there's **no typo** like `vite build` in the Netlify UI’s custom command input. It should be `yarn build` (which runs `vite build` from your scripts).
—
### ✅ 5. Re-deploy with cache cleared
In **Netlify → Deploys**, click:
– **Trigger deploy → Clear cache and deploy site**
—
### 🧪 Bonus: To verify vite is installed locally
Run:
yarn list vite
You should see output like:
vite@4.5.0
If not, install again with:
yarn add -D vite
—
Once you complete this, the `vite not found` error will be gone, and `_redirects` should work too.
Let me know if you want me to review your `package.json` directly.
6:52:11 PM: yarn run v1.22.22
6:52:11 PM: warning package.json: "dependencies" has dependency "vite" with range "^6.2.6" that collides with a dependency in "devDependencies" of the same name with version "^6.2.5"
6:52:11 PM: $ vite build
6:52:11 PM: /bin/sh: 1: vite: not found
6:52:11 PM: error Command failed with exit code 127. (https://ntl.fyi/exit-code-127)
6:52:11 PM: info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
6:52:11 PM:
6:52:11 PM: "build.command" failed
6:52:11 PM: ────────────────────────────────────────────────────────────────
6:52:11 PM:
6:52:11 PM: Error message
6:52:11 PM: Command failed with exit code 127: yarn build (https://ntl.fyi/exit-code-127)
6:52:11 PM:
6:52:11 PM: Error location
6:52:11 PM: In Build command from Netlify app:
6:52:11 PM: yarn build
6:52:11 PM:
6:52:11 PM: Resolved config
6:52:11 PM: build:
6:52:11 PM: base: /opt/build/repo/dist
6:52:11 PM: command: yarn build
6:52:11 PM: commandOrigin: ui
6:52:11 PM: publish: /opt/build/repo/dist
6:52:11 PM: publishOrigin: ui
6:52:11 PM: redirects:
6:52:11 PM: – from: /*
status: 200
to: /index.html
—
### 🧨 Problem Summary
You're seeing:
"dependencies" has dependency "vite" with range "^6.2.6" that collides with a dependency in "devDependencies" of the same name with version "^6.2.5"
…and still:
/bin/sh: 1: vite: not found
This means:
– Vite is installed **in both** `dependencies` **and** `devDependencies`, which causes confusion.
– Netlify might be using the wrong one or neither at all.
—
## ✅ Fix It Step-by-Step
—
### 🔁 1. Clean your `package.json` — keep only one Vite entry
Open `package.json`, remove **vite** from `dependencies`, and keep it **only in devDependencies**:
"devDependencies": {
"vite": "^6.2.6", // pick the latest one you want
...
},
"dependencies": {
// no "vite" here
}
Then run:
yarn install
—
### 🧹 2. Clean old install (optional but recommended)
rm -rf node_modules
rm yarn.lock
yarn install
This ensures no broken Vite symlinks.
—
### 📦 3. Verify Vite is installed locally
yarn list vite
You should now see:
vite@6.2.6
—
### 🧪 4. Test local build
yarn build
You should see:
vite v6.x.x building...
✓ built in ...
—
### 🚀 5. Commit and Push
git add .
git commit -m "Fix: remove vite version conflict"
git push
—
### 🛠️ 6. Netlify Build Settings (double-check)
In Netlify dashboard → **Site Settings > Build & Deploy > Build Settings**:
– **Build command**: `yarn build`
– **Publish directory**: `dist`
Then go to **Deploys** tab and click:
– **Trigger deploy → Clear cache and deploy site**
—
### ✅ 7. Test Again
Your site should now build without the vite error, and `_redirects` will work too (if it's in `public/` folder).
—
Let me know if you want me to check your `package.json` or share a Git repo — I can validate it line by line.
"name": "frontend",
"version": "0.0.0",
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"@mdi/font": "^7.4.47",
"@vueup/vue-quill": "^1.2.0",
"apexcharts": "^4.5.0",
"axios": "^1.8.1",
"firebase": "^11.4.0",
"firebase-admin": "^13.2.0",
"nprogress": "^0.2.0",
"pinia": "^3.0.1",
"vee-validate": "^4.15.0",
"vite": "^6.2.6",
"vue": "^3.5.13",
"vue-router": "^4.5.0",
"vue-tabler-icons": "^2.21.0",
"vue3-apexcharts": "^1.8.0",
"vue3-perfect-scrollbar": "^2.0.0",
"vue3-print-nb": "^0.1.4",
"vuetify": "^3.7.15"
},
"devDependencies": {
"@tsconfig/node22": "^22.0.0",
"@types/jsdom": "^21.1.7",
"@types/node": "^22.13.4",
"@vitejs/plugin-vue": "^5.2.1",
"@vitejs/plugin-vue-jsx": "^4.1.1",
"@vitest/eslint-plugin": "1.1.31",
"@vue/eslint-config-prettier": "^10.2.0",
"@vue/eslint-config-typescript": "^14.4.0",
"@vue/test-utils": "^2.4.6",
"@vue/tsconfig": "^0.7.0",
"eslint": "^9.20.1",
"eslint-plugin-vue": "^9.32.0",
"jiti": "^2.4.2",
"jsdom": "^26.0.0",
"npm-run-all2": "^7.0.2",
"prettier": "^3.5.1",
"sass-embedded": "^1.86.0",
"typescript": "~5.7.3",
"vite-plugin-vue-devtools": "^7.7.2",
"vitest": "^3.0.5",
"vue-tsc": "^2.2.8"
}
}
$ yarn build
6:55:11 PM: yarn run v1.22.22
6:55:11 PM: $ vite build
6:55:11 PM: /bin/sh: 1: vite: not found
6:55:11 PM: error Command failed with exit code 127. (https://ntl.fyi/exit-code-127)
6:55:11 PM: info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
6:55:11 PM:
6:55:11 PM: "build.command" failed
6:55:11 PM: ────────────────────────────────────────────────────────────────
6:55:11 PM:
6:55:11 PM: Error message
6:55:11 PM: Command failed with exit code 127: yarn build (https://ntl.fyi/exit-code-127)
6:55:11 PM:
6:55:11 PM: Error location
6:55:11 PM: In Build command from Netlify app:
6:55:11 PM: yarn build
6:55:11 PM:
6:55:11 PM: Resolved config
6:55:11 PM: build:
6:55:11 PM: base: /opt/build/repo/dist
6:55:11 PM: command: yarn build
6:55:11 PM: commandOrigin: ui
6:55:11 PM: publish: /opt/build/repo/dist
6:55:11 PM: publishOrigin: ui
6:55:11 PM: redirects:
6:55:12 PM: – from: /*
status: 200
to: /index.html
### 🔥 Problem
You have `vite` listed in **`dependencies`**, not in **`devDependencies`**, and Netlify can’t locate it at runtime during build. In rare edge cases, some Netlify build environments don't link the binary correctly unless it's in `devDependencies`.
—
## ✅ Final Fix (Guaranteed to Work)
### ✅ 1. Move `vite` from `dependencies` to `devDependencies`
Edit your `package.json` like this:
#### ❌ Remove from `dependencies`:
"vite": "^6.2.6",
#### ✅ Add to `devDependencies`:
"devDependencies": {
...
"vite": "^6.2.6",
...
}
—
### ✅ 2. Clean & Reinstall
Run these commands in terminal:
rm -rf node_modules yarn.lock
yarn install
This ensures a clean install and binary linking.
—
### ✅ 3. Re-check that `vite` works
Try building locally:
yarn build
If you see output like:
vite v6.2.6 building for production...
You're good to go.
—
### ✅ 4. Commit and Push to Git
git add .
git commit -m "fix: move vite to devDependencies"
git push
—
### ✅ 5. Netlify Settings (double check)
– **Build Command**: `yarn build`
– **Publish Directory**: `dist`
– **_redirects File**: Must be in `public/_redirects`
—
### ✅ 6. Trigger Fresh Netlify Build
Go to Netlify dashboard → **Deploys** → **Trigger deploy** → **Clear cache and deploy site**
—
After this, the **`vite not found`** issue will be resolved, and everything including inner routes and `_redirects` will work smoothly.
Let me know once done — happy to verify final logs or help with a test deploy.