Skip to content

How to remove # from URL and 404 reload issue in angular build and nodejs application?

I have Angular9 and nodejs application. I am doing ng build --prod for production build and putting that build file inside nodejs public folder and now i am able to access the page perfectly.

but my problem is in URL i want to remove #. Currentlly i am getting as

http://localhost:8080/#/about

http://localhost:8080/#/admin/create/blog

I user some technique to over come this like i use

  1. {useHash: false}
  2. PathLocationStrategy : using this i did angular build and put that build folder in Nodejs Public folder. And in url # is not showing. But when i tried to reload that it is showing 404 not found error.

I know there will be some extra things need to be added in Nodejs code. But i am not sure how to do this. I check lots of solutions but not able to fix this

I want URL not to append # and if i refresh it should not throw any 404 error. can anyone guide me how to resolve this?

Project structure:

enter image description here

NodeJs code index.js

const express = require('express')
require('./db/mongoose')
const bodyParser = require('body-parser')
const path = require("path")
const app = express()
const port = process.env.PORT || 8080

let blogRouter = require('./routes/blogRouter');

app.use(express.static(path.join(__dirname, '/public/dist/blog-ui')))
app.use(bodyParser.urlencoded({ extended: 'true' }))
app.use(bodyParser.json({ limit: "50mb" }))
app.use((req, res, next) => {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, x-token, authorization");
    res.header("Access-Control-Expose-Headers", "x-token, authorization");
    res.header("Access-Control-Allow-Methods", "PUT, POST, DELETE, GET, OPTION");
    next();
});

app.listen(port, () => {
    console.log(`Server listening on ${port}... `)
});

app.get('/*', (req, res) => res.sendFile(path.join(__dirname)));

app.use('/api/v1/blog', blogRouter);

Answer

I found one npm package, which is using browser history to load the pages. which is fixing my above issue.

Npm Package: https://www.npmjs.com/package/connect-history-api-fallback

What i followed in my code:

Angular App:

  1. Removed HashLocationStrategy, LocationStrategy and { useHash: true } from my code. I mean not adding any code which is use for resolving reload issue and which was appending # in URL. I removed this related code.
  2. build: ng build –prod

  3. copy the dist folder to nodejs public folder

Node and Express Js project change:

i just changed in index.js file.

  1. install above npm package : npm i connect-history-api-fallback --save
  2. Did code change in index.js. below code i have added in index.js

What i changed in Index.js

const history = require('connect-history-api-fallback');
const staticFileMiddleware = express.static(path.join(__dirname, '/public/dist/blog-ui'));
app.use(staticFileMiddleware);
app.use(history({
    disableDotRule: true,
    verbose: true
}));
app.use(staticFileMiddleware);

Index.js full code

const express = require('express')
require('./db/mongoose')
const bodyParser = require('body-parser')
const path = require("path")
const app = express()
const port = process.env.PORT || 8080
const history = require('connect-history-api-fallback');

let blogRouter = require('./routes/blogRouter');

const staticFileMiddleware = express.static(path.join(__dirname, '/public/dist/blog-ui'));
app.use(staticFileMiddleware);
app.use(history({
    disableDotRule: true,
    verbose: true
}));
app.use(staticFileMiddleware);

app.use(bodyParser.urlencoded({ extended: 'true' }))
app.use(bodyParser.json({ limit: "50mb" }))
app.use((req, res, next) => {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, x-token, authorization");
    res.header("Access-Control-Expose-Headers", "x-token, authorization");
    res.header("Access-Control-Allow-Methods", "PUT, POST, DELETE, GET, OPTION");
    next();
});

app.listen(port, () => {
    console.log(`Server listening on ${port}... `)
});

app.get('/*', (req, res) => res.sendFile(path.join(__dirname)));

app.use('/api/v1/blog', blogRouter);