---
title: "Vite Pre-built Subpath Workaround — <base href>"
tags: [concepts, vite, apache, spa, deploy, subpath, auto-generated]
source: loreal-timelog-viewer
created: 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:

```html
<!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:

```apache
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

## Related

- [[wiki/tech-patterns/apache-spa-proxy-configuration-with-includes]] — full Apache SPA + API proxy pattern, FallbackResource, ProxyPassMatch
- [[wiki/connections/optical-dev-apache-vite-basepath]] — standard Vite `base` config approach for projects where source is available
