obsidian/wiki/concepts/vite-prebuilt-subpath-workaround.md
2026-05-05 11:22:10 +01:00

2.8 KiB

title tags source created
Vite Pre-built Subpath Workaround — <base href>
concepts
vite
apache
spa
deploy
subpath
auto-generated
loreal-timelog-viewer 2026-05-05

Vite Pre-built Subpath Workaround — <base href>

Problem

Vite builds without a configured base option always generate absolute asset paths (e.g., /assets/index-abc123.js). When such a pre-built dist/ is deployed to a subpath like /timelog/, the browser requests /assets/... instead of /timelog/assets/... — all assets 404.

The standard fix is to set base: "/timelog/" in vite.config.ts and rebuild. But if you only have the pre-built dist/ and no source code, rebuilding is not an option.

Workaround: <base href> HTML Tag

Insert a <base> tag into dist/index.html before any asset references:

<!DOCTYPE html>
<html>
  <head>
    <base href="/timelog/">
    <!-- ... -->
    <script type="module" crossorigin src="./assets/index-abc123.js"></script>
  </head>
</html>

The browser resolves all relative URLs from that base, so ./assets/... becomes /timelog/assets/... — matching where Apache serves the files.

[!warning] Relative paths required This only works if asset src/href values use relative paths (./assets/...), not absolute ones (/assets/...). Vite's default output uses ./-prefixed relative paths when no base is set, which is exactly what makes this trick work.

When to Use

  • You have a pre-built Vite dist/ with no access to source
  • The app must be served at a URL subpath, not the domain root
  • Rebuilding is not possible (received binary, CI artifact, external vendor, etc.)

Apache Configuration

After fixing index.html, Apache still needs to serve the SPA correctly:

Alias /timelog/ /var/www/html/timelog/
<Directory /var/www/html/timelog/>
    Require all granted
    FallbackResource /timelog/index.html
</Directory>

FallbackResource is essential for client-side routing — see wiki/tech-patterns/apache-spa-proxy-configuration-with-includes for the full pattern.

Nested Git Repository Gotcha

When a project directory is inside a parent git repository, running git init + git push from the project root creates an independent repo inside the parent. Git treats it as a submodule if the parent has it tracked. To push cleanly:

  1. cd /path/to/project
  2. git init && git add . && git commit -m "init"
  3. Add a new remote and push — do NOT use the parent repo's remote
  4. If the parent accidentally staged the subdir as a submodule, git rm --cached <dir> in the parent