-
Notifications
You must be signed in to change notification settings - Fork 87
Description
1. Description
When using django-vite
in development mode (DJANGO_VITE_DEV_MODE = True
), the URL generated by the {% vite_asset %}
template tag for assets served by the Vite development server incorrectly includes the Django settings.STATIC_URL
prefix.
This results in the browser attempting to fetch assets from an incorrect URL, leading to 404 errors. For example, instead of requesting http://localhost:5173/src/main.ts
, the browser requests http://localhost:5173/static/src/main.ts
.
2. Code Analysis
The issue appears to stem from the get_dev_server_url
method within the DjangoViteAppClient
class (located in django_vite/core/asset_loader.py
). Specifically, this section:
# Inside django_vite/core/asset_loader.py -> DjangoViteAppClient.get_dev_server_url
def get_dev_server_url(
self,
path: str,
) -> str:
# ... (docstring)
static_url_base = urljoin(settings.STATIC_URL, self.static_url_prefix) # Incorrectly uses STATIC_URL
if not static_url_base.endswith("/"):
static_url_base += "/"
# This line combines the vite server base with a path that already includes STATIC_URL
return urljoin(
f"{self.dev_server_protocol}://"
f"{self.dev_server_host}:{self.dev_server_port}",
urljoin(static_url_base, path), # The inner urljoin creates "/static/path/to/asset"
)
This code explicitly constructs the asset path by joining settings.STATIC_URL
with the provided path
, even when dev_mode
is True
. The Vite development server, however, serves assets relative to its configured root
directory and does not expect the Django STATIC_URL
prefix.
3. Steps to Reproduce
- Configure Django Settings (
settings.py
):- Set
DEBUG = True
- Set
DJANGO_VITE_DEV_MODE = True
(or link it toDEBUG
) - Set
STATIC_URL = '/static/'
(ensure trailing slash) - Configure
DJANGO_VITE_ASSETS_PATH
andDJANGO_VITE_MANIFEST_PATH
appropriately (though manifest isn't used in dev mode).
- Set
- Configure Vite (
vite.config.js
orvite.config.ts
):- Set
root
to your frontend directory (e.g.,frontend/
). - Set
base: '/'
for development mode. Example dynamic config:// vite.config.js import { defineConfig } from 'vite' export default defineConfig({ // ... plugins root: 'frontend', // Or path relative to config file base: process.env.NODE_ENV === 'production' ? '/static/' : '/', // ... server, build configs })
- Ensure you have an entry point (e.g.,
frontend/src/main.ts
).
- Set
- Use Template Tag (
your_template.html
):- Load the tags:
{% load django_vite %}
- Include the asset:
{% vite_asset 'src/main.ts' %}
(path relative to Viteroot
)
- Load the tags:
- Run Servers:
- Start the Vite development server:
npm run dev
(oryarn dev
) in the frontend directory. - Start the Django development server:
python manage.py runserver
- Start the Vite development server:
- Observe:
- Load the Django page in your browser.
- Inspect the HTML source code for the
<script>
tag generated byvite_asset
. - Check the browser's Network tab.
4. Expected Behavior
The {% vite_asset 'src/main.ts' %}
tag should generate a <script>
tag with the src
attribute pointing directly to the Vite development server, without the STATIC_URL
prefix.
Example Expected src
: http://localhost:5173/src/main.ts
5. Actual Behavior
The {% vite_asset 'src/main.ts' %}
tag generates a <script>
tag with the src
attribute that incorrectly includes the STATIC_URL
prefix.
Example Actual src
: http://localhost:5173/static/src/main.ts
This leads to a 404 error in the browser's console when trying to fetch the asset from the Vite dev server.
6. Environment
- django-vite version:
3.1.0
- Django version:
5.1.6
- Python version:
3.11.3
- Node.js version:
v22.14.0
- npm / yarn version:
npm 11.2.0
- Vite version:
6.2.5
- Operating System:
Windows 11
7. Suggested Fix (Optional)
Modify the get_dev_server_url
method in django_vite/core/asset_loader.py
to avoid using settings.STATIC_URL
when constructing the URL:
# Inside DjangoViteAppClient.get_dev_server_url
from urllib.parse import urljoin
def get_dev_server_url(
self,
path: str,
) -> str:
# Base URL of the Vite development server MUST end with / for urljoin
vite_server_base_url = f"{self.dev_server_protocol}://{self.dev_server_host}:{self.dev_server_port}/"
# Combine the Vite base URL directly with the asset path (relative to Vite root)
# Use lstrip('/') on path to prevent potential double slashes if path starts with /
final_url = urljoin(vite_server_base_url, path.lstrip('/'))
return final_url
8. Related Issues Checked
I have reviewed issues #44 and #47.
- Issue Possible urljoin issues with DJANGO_VITE_STATIC_URL_PREFIX #44 deals with manifest path resolution using full URLs for
DJANGO_VITE_STATIC_URL_PREFIX
in production (S3 hosting). - Issue Load Static Site without the
baseUrl
orDJANGO_VITE_STATIC_URL_PREFIX
in the URL #47 discusses challenges with serving the entire Vite app from the Django root URL in production.
Neither directly addresses this specific bug concerning the incorrect construction of the asset URL pointing to the Vite development server.