I am working on an angularJS app, which has URLs in the format (in dev) -
http://localhost:6001/#/home/index
http://localhost:6001/#/content/index
As this app, will also be available on desktop browser, I wanted the URLs to be without '#', so I added this in my app's config section -
$locationProvider.html5Mode(true);
Which works fine and URLs don't show '#'. But there is a problem now. On refreshing a particular page in browser, now I get this error -
Cannot GET /home/index
Are there any other changes required to get this working?
Note: This app is using cordova CLI and is hosted on a Node.js server.
Try to put in your as your route:
app.get(*, function(req,res) {
//return the main index file
});
This will cause any unmatched route to serve the index page and from there angular take care of this route.
Try this:
Make sure you have these lines in your server.js file
var express = require('express');
var app = express();
app.use(express.static(__dirname + '/public.build'));
app.use(function(req, res) {
res.sendFile('index.html', { root: __dirname + "/public.build" });
});
Why so? Please read here - https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-configure-your-server-to-work-with-html5mode
The first step resulted in my app in the following console.log message:
Resource interpreted as Stylesheet but transferred with MIME type
text/html: "http://localhost:8080/board/css/style.css".
As you can see, the styles are trying to load from non-existent path (/board/ folder is not present in the app, it's one of the states in ui-router).
To fix it I replaced the following line
<link rel="stylesheet" href="css/style.css">
with this one:
<link rel="stylesheet" href="/css/style.css">
Related
Problem
After setting a base tag to run Angular 1.x in HTML5 mode, the browser (Chrome) makes requests to the wrong path for scripts when accessing the app by navigating directly to localhost:3000/resource/id.
Details
I have an Angular 1 app that I have recently set to run in HTML5 mode, like so:
$locationProvider.html5Mode(true);
I have included a base tag in the head of index.html like so:
<base href="/">
I have set up my express routes so that a request for (for example) http://localhost:3000/album/38ad87f will return index.html, like so:
.use('/', express.static(__dirname + '/crate-frontend/app'))
// Playlist endpoints
.use('/api/playlists', playlistRoutes)
// Album endpoints
.use('/api/album', albumRoutes)
// Artist endpoints
.use('/api/artist', artistRoutes)
// Track endpoints
.use('/api/tracks', trackRoutes)
// User endpoints
.use('/api/user', userRoutes)
// Discogs proxy endpoints
.use('/api/discogs', discogsRoutes)
// Youtube proxy endpoints
.use('/api/youtube', youtubeRoutes)
// Search endpoints
.use('/api/search', searchRoutes)
// For serving up crate-frontend/app/index.html
.all('/*', function(request, response){
response.sendFile(__dirname + '/crate-frontend/app/index.html' );
})
Now, when I go to the home page, and navigate around, everything works fine. BUT if I refresh the page that is not the root OR a copy/paste a URL like http://localhost:3000/album/38ad87f into a new window, it breaks. I can see that it receives index.html, but then when the browser requests each of the linked scripts, for example:
<script src="app.js"></script>
it actually makes a request to http://localhost:3000/album/app.js, which returns index.html.
Can someone tell me what I've missed / am doing wrong?
Try to include your ressources with an absolute path and you will be fine for all time.
<script src="/app.js"></script>
I want to remove # from my angularjs app, I am developing an website, I think it may help to make SEO friendly website, May be i am wrong, Please help
Thanks
I agree with Joe Lloyd for the way to remove the # from your url but it won't help you to make your angularjs website crawlable.
Check out the following steps :
Configure the html5mode
config(function ($routeProvider, $locationProvider) {
$locationProvider.html5Mode(true);
Add <meta name="fragment" content="!"> to your pages so the google bot knows to add the ?_escaped_fragment_= at the end of your request.
Handle the ?_escaped_fragment_=on the server side and serve a static snapshot of the requested html page (phantomjs can make the job) so the bot will index the rendered version of the html page.
Populate your sitemap.xml and send it to google using www.google.com/webmasters/
Have fun !
Config
To remove the # in your url you need to add this to your main module. You put the app into html5 mode.
//This config is used to remove the # in the html
app.config(["$locationProvider", function($locationProvider) {
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
}]);
Server Side (NodeJS)
This will have a server side effect when you hit refresh you need to add an extra route that is able to find the new url. this will work in your express js app.js file. Where the public folder contains your angular app and you have your index.html file in there
// ### CATCH REFRESH TO INDEX ###
app.all('/*', function(req, res, next) {
// Just send the index.html for other files to support HTML5Mode
res.sendFile('public/index.html', { root: __dirname });
});
I have remove (#) hashbangs by $locationProvider.html5Mode(true) in ui-route.
and set <base href="/public/">
when I have tried to localhost:59940/public/#/home url # is remove and url look localhost:59940/public/home and getting home view.
but when I have tried localhost:59940/public/home url. I have getting 404 Not Found error.
help me for getting home view when try to access localhost:59940/public/home in browser.
The problem is that the browser resolves urls before your angular app responds, and indeed the resource for that route is not there. The solution I have used is to make your 404 route return the index.html page and use ui-router to handle real 404 cases. But another idea is to match all of the client routes to routes on your server which return the index.html.
To enable $locationProvider.html5Mode in angular, you also need to some side server changes.
Other then your static assets and apis path, all other routes should server index.html(your main SPA page) only.
See below code.
This is how you can do it in node.js using express server.
var app = require('express')();
app.configure(function() {
// Static files - all js, css, images, etc go into the static path
app.use('/static', express.static('/static'));
// If a static file is invalid so we send 404
app.use('/static', function(req, res, next) {
res.send(404);
});
// This route deals enables HTML5Mode by forwarding missing files to the index.html
app.all('/*', function(req, res) {
res.sendfile('index.html');
});
});
app.listen(3000);
I'm trying to remove # from my angularjs urls using
$locationProvider.html5Mode(true);
$locationProvider.hashPrefix('!');
and <base href="/"> in my index.html and i have changed the hrefs in my partials from #/abc to /abc
it works fine when navigating through links within the site, however except my home page, on every other page, when i try to reload the page or copy and paste the link(and hit enter) it gives me error. i have done alot of search online with no luck. i'm hoping someone here has already gone through this and can help me.
thanks
So if you are using jade you shall do the following:
app.get('/', index);
// while index is defined in routes.js and jade is defined as template engine
If you're using angularjs templating engine with normal html files, do the following:
exports.index = function(req, res) {
res.sendfile(__dirname + "/public/index.html");
};
app.get('/', index);
I'm using AngularJS and ExpressJS and having an issue with routing. I saw many other posts but none of those solutions seemed to work. Here is my routes in Express:
module.exports = function(app, auth) {
//Api routes
var mycontroller = require('../app/controllers/mycontroller');
app.get('/api/dostuff/:id', mycontroller.getBlockByHash);
//Home route
app.get("/", function(req, res) {
res.render('index');
});
};
When I go to my root /, everything works as expected. ExpressJS serves up my index and angular picks up the rest. When I click a link /blocks, it works as expected since AngularJS picks up the route. But when I refresh, I get a 404 not found error.
I tried app.get('*' instead, but that gives me a completely different error where nothing loads.
I'm using Jade to create the basic page structure with Express. My Express config is:
app.use(express.favicon());
app.use(express.static(config.root + '/public'));
When using html5Mode the documentation says:
Using this mode requires URL rewriting on server side, basically you have to rewrite all your links to entry point of your application (e.g. index.html)
What it doesn't mention is:
You should exclude static assets like scripts/styles/images/fonts etc.
You should also exclude your Restful API.
Your case:
The error you got there is express serving html into script tags and the browser fails to parse them as a valid javascript.
Use express.static to serve static assets and then use app.get('*', for redirecting all other requests to your angular.js entry point (index.html).
express.js middleware order do counts!
express.static must be declared before app.router
Node.js / Express.js - How does app.router work?