7

I'm trying to convert my existing and sprawling Django project, which currently uses Vue from a CDN in individual pages on the frontend, to an SPA via NPM with the backend and frontend now separate (except for Django handling some URL routes and loading the Vue initially).

I'm running into a problem with static files and URL routing. In vue.config.js, I was originally advised to set values as follows:

const pages = {
  index: "src/main.js"
};
module.exports = {
  runtimeCompiler: true,
  publicPath: "/static/vue/",
  outputDir: "./dist/static/vue/",
  indexPath: "../../templates/vue_index.html",
  pages: pages
};

so that when combined with the way Django looks for static files:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'frontend/dist/templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'frontend/dist/static')]
STATIC_URL = '/static/'

the page will be able to load.

Unfortunately, if I try to load the page, rather than loading at the website root /, it loads at /static/vue/ (i.e. localhost:8000/static/vue/). If I try to directly access localhost:8000, it immediately redirects to localhost:8000/static/vue/, which I suppose is vue-router's doing.

Django is able to find the Vue entry point template just fine, but it seems to need publicPath: "/static/vue/" in order to prefix the .js and .css files correctly with Django's required /static/ prefix on static URLs (and even if I could change /static/ to all static files being served at /, I prefer the out-of-the-box /static/ prefix).

If I change publicPath: "/static/vue/" to publicPath: "/" or publicPath: "./", the template file is still served correctly, but I've now lost the /static/vue/ prefix that I need for the .js and .css files, so they 404.

How would I be able to tell Vue (or vue-cli, more specifically), to serve the root page of my app at / but prefix all static files referenced in the initial template with /static/ or /static/vue/?

1 Answer 1

10

Eventually found the answer. For Vue 3, set the base URL in the vue-router:

const router = createRouter({
  history: createWebHistory("/"),
  routes
});
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, It helped me. If you have sub-path like my-app then we can use createWebHistory("/my-app/")
Thanks, you saved my life! Played around for two days with different vite.config.ts experiments and hooks and custom injections into the static asset files... Really annoying, this is the cleanest way so far.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.