Github deployment 404 on refresh - vue.js

I've tried following this guide https://cli.vuejs.org/guide/deployment.html#github-pages
I've included in vue.config.js
module.exports = {
publicPath: process.env.NODE_ENV === 'production'
? '/my-app/'
: '/'
}
Seems to work when I've deployed this to my Gh, but whenever I press F5 on any page, I get 404:
404
File not found
The site configured at this address does not contain the requested file.
If this is your site, make sure that the filename case matches the URL.
For root URLs (like http://example.com/) you must provide an index.html file.

Related

vuejs history mode with github/gitlab pages

Has anyone managed to figure out how to make Vue.js work with history mode with GitHub or GitLab Pages?
It works with hash mode, but I don't want to use hash mode for SEO related reasons.
Reference for router modes: https://router.vuejs.org/en/essentials/history-mode.html
I found a solution that works for me in this article.
To summarize the solution, I created the following 404.html file and added it to the project's root folder.
<!DOCTYPE html>
<html>
<head>
<script>
// ====================================================================================================================
// This text is simply to make sure the 404.html file is bigger than 512 bytes, else, internet explorer will ignore it.
// Thank you internet explorer for requiring such awesome workarounds in order to work properly
// ====================================================================================================================
sessionStorage.redirect = location.href;
</script>
<meta http-equiv="refresh" content="0;URL='/'">
</head>
</html>
I then added this javascript in the index.html:
(function(){
var redirect = sessionStorage.redirect;
delete sessionStorage.redirect;
if (redirect && redirect != location.href) {
history.replaceState(null, null, redirect);
}
})();
Not sure about GitLab Pages, but in GitHub Pages you can serve your whole Vue.js Application through the 404.html file instead of the index.html file. Simply rename the index.html file to 404.html file on deploy.
EDIT:
As pointed out in the comments, this has the side effect of having GitHub/GitLab serve your website with a 404 status code.
Run into same issue, found this question & tried both solution above but no luck. Then tried combine them like this:
Here my 404.html file
<!DOCTYPE html>
<html>
<head>
<title>My App</title>
<script>
// ========================================
// Credits:
// - https://stackoverflow.com/a/50259501
// - https://stackoverflow.com/a/50247140
// ========================================
const segment = 1
sessionStorage.redirect = '/' + location.pathname.slice(1).split('/').slice(segment).join('/')
location.replace(
location.pathname.split('/').slice(0, 1 + segment).join('/')
)
</script>
</head>
</html>
And here's my main.js file
const app = new Vue({
router,
store,
render: h => h(App),
created () {
if (sessionStorage.redirect) {
const redirect = sessionStorage.redirect
delete sessionStorage.redirect
this.$router.push(redirect)
}
}
})
app.$mount('#app')
And it works
https://feryardiant.github.io/static-spa/foo/bar/baz
https://feryardiant.gitlab.io/static-spa/foo/bar/baz
GitLab Answer
For those using GitLab there is now support to redirect to index.html using a _redirects file in your public folder.
Steps:
Create a file named _redirects in the public folder
Add this snippet line to that file
/* /index.html 200
Documentation: https://docs.gitlab.com/ee/user/project/pages/redirects.html#rewrite-all-requests-to-a-root-indexhtml
A little late to the party but I have a method to do this. I am using Vue CLI 3 and GitHub pages.
First of all, I commit all the source file into a source branch, and commit the dist folder (generated by Vue) to the master branch using the following shell command:
# deploy.sh
#!/usr/bin/env sh
# abort on errors
set -e
# build
echo Building. this may take a minute...
npm run build
# navigate into the build output directory
cd dist
# create a copy of index.html
cp index.html 404.html
find . -name ".DS_Store" -delete
# if you are deploying to a custom domain
echo 'custom.com' > CNAME
# remove git and reinitialise
rm -rf .git
echo Deploying..
git init
git add -A
git commit -m 'deploy'
# deploy
git remote add origin https://github.com/User/repo.github.io
git push origin master --force
cd -
rm -rf dist
When GitHub pages can't find the route, it uses 404.html. The deploy program I wrote makes a copy of index.html and names it 404.html. That's why it works.
Edit
Just realised that this wouldn't be good for SEO purposes as it returns a 404 response and Google won't index it.
You could use a 404.html hack https://github.com/rafrex/spa-github-pages/blob/gh-pages/404.html
Or you can try to pre rendering your vue into static html
https://nuxtjs.org/guide#static-generated-pre-rendering-
Based on Fery's solution, I think instead of handling redirect when creating Vue instance, the Navigation Guards could work better.
I basically added a beforeEnter guard for the index route, so that the index page will be skipped and directly go to the target page.
const routes = [
{
path: '/',
component: Index,
beforeEnter: (to, from, next) => {
if (sessionStorage.getItem('redirect') !== null) {
const redirect = sessionStorage.redirect
delete sessionStorage.redirect
next(redirect)
} else {
next()
}
}
},
]
Hope this is helpful.
2021 Solution for vue3 & vue-cli:
Follow this with "Basic instructions":
https://github.com/rafgraph/spa-github-pages#usage-instructions
no need to change var pathSegmentsToKeep = 0; the 404.html.
and then in the vue.config.js:
// do not use "./dist/"
publicPath: "/dist/",
// make the index.html file place at the root of the repo
indexPath: "../index.html",
then the spa is good to go~

webpack-dev-middleware serve/fallback to the public directory

Project structure:
Webpack is building the app into the public folder
At the same time I have some static assets located there, like:
public/assets/font-awesome-4.7.0/css/font-awesome.css
What I want:
I want to run my express app with the webpack-dev-middleware for the dev purposes
I want that all the requests for the static assets (which are not processed by webpack) were served from the public folder
How I tried to do that:
first attempt
app.use(require('webpack-dev-middleware')(compiler, {
stats: { colors: true }
}));
app.use(require('webpack-hot-middleware')(compiler));
app.use('/', feathers.static(app.get('public'))); // express.static
This works good, until you have index.html in the public folder. If you have it there - the static one would be served, NOT the one which is the actual version according to the webpack-dev-middleware.
second attempt
Then I thought - probably I must use express.static only for the production case, I removed it. Now I was not able to open /assets/font-awesome-4.7.0/css/font-awesome.css
third attempt (hack which works right now)
Finally I made it work, but I'm not satisfied with the current solution. I manually put all the assets directory into the webpack realm by extending the webpack config with this:
new CopyWebpackPlugin([
{ from: 'public/assets/', to: 'assets' },
{ from: 'node_modules/bootstrap/dist/', to: 'vendor/bootstrap/dist' }
]),
however this method assumes that one need to point every static file which he wants to be served by webpack-dev-middleware
Any thoughts are appreciated.
Regards,

Aurelia plugin path error

I installed aurelia-breadcrumbs using jspm. config.js file has a map entry:
"heruan/aurelia-breadcrumbs": "github:heruan/aurelia-breadcrumbs#0.2.6"
The config.js also has a path entry:
"github:*": "jspm_packages/github/*"
In my project under the directory jspm_packages/github/heruan, there are files/folders relating to aurelia-breadcrumbs.
In my boostrap config I have:
aurelia.use
.standardConfiguration()
.feature('src/resources')
.developmentLogging()
.plugin("heruan/aurelia-breadcrumbs");
However, the plugin is not being mapped properly and it cannot find the aurelia-breadcrumbs.js file (error 404 in the browser).
Uncaught (in promise) Error: (SystemJS) XHR error (404 Not Found) loading http://localhost:7987/heruan/aurelia-breadcrumbs.js
When I look in the 'sources' tab in chrome developer tools, the breadcrumbs plugin no longer appears under jspm_packages/github.
What am I missing?
In the /jspm_packages/github/heruan/aurelia-breadcrumbs#0.2.6/dist/commonjs/index.js file, please change this
function configure(frameworkConfiguration, config) {
frameworkConfiguration.globalResources('./breadcrumbs.js');
}
from
function configure(frameworkConfiguration, config) {
frameworkConfiguration.globalResources('/jspm_packages/github/heruan/aurelia-breadcrumbs#0.2.6/dist/commonjs/breadcrumbs.js');
}
this change is because,index.js file is unable to load ./breadcrumbs.js due to some path issue or some other,instead if we provide relative path then it is loading the file

XS engine, 404 on non-HTML files

Having made a .xsaccess file and a .xsapp file, I can access my UI5 application on https://host:8000/app/index.html. It does however give me 404's on non-HTML files in the same folder and subfolders, for instance my manifest, Component and other JS files. XSJS files seem OK.
Am I missing a setting somewhere?
Try adding the following code in your .xsaccess and see if it works.
{
"exposed" : true,
"authentication" : [{"method":"Basic"}],
"cache_control" : "no-cache, no-store",
"cors" : {
"enabled" : false
}
}

Stylus middleware in Express not working?

In app.coffee I have
stylus = require("stylus")
...
app.use stylus.middleware
debug: true
src: __dirname + "/stylus"
dest: __dirname + "/public/css"
compile: (src) ->
console.log(stylus(src))
return stylus(src)
I included the styles in layout.jade like:
link(rel="stylesheet", href="/css/styles.css")
But in Chrome network tab, I see canceled for styles.css why is that?
When I point the browser directly to /css/styles.css, I get
Cannot GET /css/styles.css
Whats wrong? How do I fix this?
Do you have the static middleware properly configured and working and positioned AFTER the stylus middleware in your middleware stack? The stylus middleware is just going to read the .styl file and write the corresponding .css file but it expects the static middleware to then find the .css file and serve it.
Also note that your src and dest file hierarchies should correspond directly. By that I mean even counting all intermediate directories if you list the recursive contents of one directory (ls -R or similar) then the ONLY difference should be src contains .styl files and dest contains exactly corresponding .css files. Don't tack a /css prefix onto one but not the other, for example.
Recently I run into the same issue and as long as #PeterLyons answer is correct I found that adding the extra slash after css directory name also seems to fix the problem.
(without coffee)
var stylus = require('stylus');
app.configure(function() {
app.use(stylus.middleware({
src: __dirname + '/stylus',
dest: __dirname + '/public/css/' // <-- additional slash after "css"
}));
app.use(express.static(__dirname + '/public'));
});
Not sure if this is stylus version-related issue and wasn't/was present before but still it's quite confusing to me.
This has been driving me crazy for a few hours so I thought I'd share :)
I serve my external files from /public
So my stylesheets are in /public/styles. All I had to do was put my .styl files in a folder called /styles in the root of my project.
modules.app.use(modules.stylus.middleware({
debug: true,
src: __dirname + '/',
dest: __dirname + '/public/',
compile: compile
}));
I got around the whacky path requirements as I'm always going to ask for styles in /styles
GET /styles/website.css serves /styles/website.styl from the root / directory of the project
this worked for my
app.use(express.static('public'));
//stylus
function compile(str, path) {
return stylus(str)
.set('filename', path)
}
app.use(stylus.middleware(
{ src:'/public/css'
, compile: compile
}
));
put your file.styl in public.css it will be compiled there too!
the problem must be the src directory, it seems you are pointed to modules/stylus, anywhere I am not an exprert but this way works