Assets in Vue app not loading when published to Github pages

Viewed 1810

I'm publishing my SPA that I'm making with Vue and Buefy to my a gh-pages branch a of private repo, just so I can test if everything will load normally.

Later, I'll upload the finished website to the actual public repo, which is tied to my custom URL (I'm redesigning the website from scratch, using a diff tech).

Since Vue websites needs to be built for distribution, I'm using an NPM package to do this for me: https://github.com/KieferSivitz/vue-gh-pages

"deploy": "node ./node_modules/vue-gh-pages/index.js --branch gh-pages -m \"Deploy to gh-pages.\""

When deploying the website, it loads only partially. The images won't load, and the router will not work (links to other pages won't work).

I'm storing images in the assets folder, and using require('@/assets/logo.png') to load them (at least it works with localhost).

The images are trying to be loaded from https://<username>.github.io/img/logo.d2151712.png.

I read that I would need to set the publicPath to my project name, since currently the website is being served from https://<userName>.github.io/<projectName>/, but with that, the whole website is 404-ing.

With that property, the whole website would try to load from https://<username>.github.io/<projectName>/<projectName>.

I think that somewhere, there's a setting adding <projectName> to router, but not adding elsewhere.

Edit

I tried to force vue-router to get the correct base, without setting the publicPath:

base: "<projectName>/", //process.env.BASE_URL,

But the routes are stil not working, since I'm lazy loading them using import("@/views/Page.vue").

3 Answers

It seems that your issue is, that you want to run your Vue app in a subfolder of a domain (domain.com/subfolder/index.html). This needs to be configured in Vue CLI. Add a new file to the root of your repository, called vue.config.js and add the following content:

module.exports = {
  publicPath: process.env.NODE_ENV === 'production' ? '/subfolder/' : '/',
};

This will set the webpack publicPath to /subfolder/ when running the build process in production mode. If you are using Vue CLI < 3.3, you need to use baseUrl instead. You need to make sure, that your path starts with a slash.

See also the documentation of publicPath.


Vue CLI has also a special section for the deployment to GitHub pages. You might also want to take a look at this: https://cli.vuejs.org/guide/deployment.html#github-pages

I read that I would need to set the publicPath to my project name, since currently the website is being served from https://.github.io//, but with that, the whole website is 404-ing.

Indeed, the publicPath property is required to be set to the GitHub repo name, surrounded by slashes (i.e., /github_repo_name/). The 404's are caused by vue-gh-pages removing the leading slash from URLs in index.html:

<!-- <script src=/github-pages-vue-demo/js/chunk-vendors.c4b075fb.js></script> --> <!-- before -->
<!-- <script src=/github-pages-vue-demo/js/app.9b45ea45.js></script> --> <!-- before -->
<script src=github-pages-vue-demo/js/chunk-vendors.c4b075fb.js></script>
<script src=github-pages-vue-demo/js/app.9b45ea45.js></script>

With that property, the whole website would try to load from https://<username>.github.io/<projectName>/<projectName>.

That's a side effect of the slash-removal, making the URLs relative. Relative URLs are relative to the current location (appended to the current directory). For example, with this GitHub pages URL - https://tony19-sandbox.github.io/github-pages-vue-demo/, a relative URL of github-pages-vue-demo/js/app.9b45ea45.js would resolve to:

https://tony19-sandbox.github.io/github-pages-vue-demo/github-pages-vue-demo/js/app.9b45ea45.js

And an absolute URL of /github-pages-vue-demo/js/app.9b45ea45.js would resolve to:

https://tony19-sandbox.github.io/github-pages-vue-demo/js/app.9b45ea45.js

I think that somewhere, there's a setting adding <projectName> to router, but not adding elsewhere.

vue-router has a base property for that purpose, but Vue CLI (@vue/cli-plugin-router) correctly defaults it to process.env.BASE_URL. That environment variable is already equal to publicPath from your Vue CLI config, so there's no need to set it.

Workaround

If you wish to continue using vue-gh-pages, you could use patch-package to disable the slash-removal (index.js line 109) as shown below:

//editForProduction();
if (repository !== null) {
    pushToGhPages();
}

GitHub demo

Otherwise, I would skip that library entirely, and use gh-pages directly in a deploy script.

Vue has a configuration for that. If you use vue client then add vue.config.js the next lines por public path property

module.exports = { publicPath: process.env.NODE_ENV === 'production' ? './':'/' };

Related