Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Building and deploying

During development the Vite server processes .vue files on the fly. For deployment the project is built: Vite turns components into plain HTML, CSS and JavaScript files, minifies them and puts them into the dist/ folder. That folder can be uploaded to any static file hosting.

Building

In the blog project folder run:

npm run build

The terminal lists the created files with their sizes, and a dist/ folder appears in the project:

dist/
├── index.html
├── favicon.ico
└── assets/
    ├── index-BkX3c9aQ.js
    ├── index-D1f8Lw2e.css
    └── AdminLayout-Cq7nR0sd.js

The odd endings in the names are content hashes. When the code changes, the file name changes, and the visitor's browser does not take the old version from its cache. Separate files for pages exist thanks to lazy-loaded routes.

Checking the build

npm run preview

The command starts a simple server for the dist/ folder at http://localhost:4173. Walk through the blog pages: this way you check exactly what will end up on the server.

Environment variables

The API address is better kept out of the code, in a .env file at the project root. Only variables with the VITE_ prefix reach the code:

VITE_API_URL=https://jsonplaceholder.typicode.com
// src/stores/posts.js
const API = `${import.meta.env.VITE_API_URL}/posts`

For the build you can create a separate .env.production file — Vite uses it on npm run build. Values are inserted into the code at build time, so never keep secret keys in such variables: any visitor can see them in the JavaScript files.

The base path

If the site is served not from the domain root but, for example, from https://example.com/blog/, set this in vite.config.js:

// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
 
export default defineConfig({
  plugins: [vue()],
  base: '/blog/',
})

Vite prefixes all file paths with /blog/, and the router gets this path through import.meta.env.BASE_URL — it is already passed to createWebHistory.

Server setup

The router in createWebHistory mode uses ordinary addresses like /posts/5, but there is no such file on the server. The server must return index.html for any unknown address, and the router then picks the page. For nginx it is one line in the location block:

location / {
    try_files $uri $uri/ /index.html;
}

Static site hosts — Netlify, Vercel, Cloudflare Pages — usually offer such a rule in their settings for Vite projects or detect it themselves.

Common mistake

You deploy the site, open the home page — everything works, but reloading /posts/5 gives a 404 error. The server looks for a file posts/5 and cannot find it, because the routes exist only in JavaScript. Set up returning index.html for every address, as in the section above, and check it by reloading a nested page after deploying.

Thanks for reading!

Donate to the site — we work hard for you.