I'm currently building a single page app using backbone.js
In order to keep all application pages accessible and crawl-able I made sure that the server side can also render the pages when accessing them directly.
The problem is as follows:
When pushState is not available it initiates the router using the current URL (e.g. if I accessed a url with http://example.com/example the router will build the hash fragment on top of that url)
So:
Is there any way of handling this (besides redirecting the use)
If you are redirecting as soon as the JS (using pushState feature detection) you still have a problem of urls not having hash signs.
Generally asking, is there a better approach of designing this kind of application?
Thanks!
I think the evolving consensus is pushstate or nothing (ie to degrade web 1.0 and drop hash-bang routing all together) if SEO-friendly browsing matters to you.
Its one of the reasons I don't use Backbone.js and just use PJAX is that pushstate and DOM rendering times are so good you can be single page with very little JS and hash-bang routing has always been rather hackish.
Thus an option is to not use Backbone's router all together and just let something like PJAX (or DJAX or something similar) do the routing work and let Backbone just do the inner page event/rendering stuff (ie validating forms, modal windows, etc..).
Related
Using AngularJS 1.5.8 and Django/Django REST Framework as the back-end.
At this points have two URLs (app/ for login and app/dashboard as the main content); would be great to just have app/.
login and dashboard I have as components; navbar and sidebar I have as directives.
Using ngRoute currently and somethings I am reading lead me to believe I should be using ui-router to accomplish this.
Just some basic things that came to mind.
My sidebar has several tools I am developing. I want the user to be able to click on them, and then have the content related to that tool load in the main content area without the page refreshing or the URL changing.
Some of what I have read suggests ui-router might be better for this purpose? I am not, sure as I am just learning AngularJS and still struggling with its concepts. Thus, I don't have any code to post that needs to be fixed. Primarily just trying to understand the concepts and technology I need to look into to accomplish this. Makes it hard to lookup results on Google and SO when you aren't even sure what the terminology and tech is that you should be looking for.
Not sure if ngRoute or ui-router should be used; whether the modules should be built as components or directives; if the content for each tool stays in its own HTML template; etc...
This is a somewhat broad question but what you are looking for is client-side routing. Both ngRoute and ui-router offer this functionality and in very similar ways except ui-router offers significant extensibility with nested routes and multiple named view containers.
My advice is to start with ngRoute and learn it's ins and outs and then switch to ui-router if you find you need this extra functionality.
Client-side routing can either be used with the hash-bang (#/) or using html5 mode you can use a base URL that would function visually like server-side routing.
Now you've got the terms to search at least so happy Googling!
As far as I know the hash symbol(#) is the key when implementing routing in Angular. The web server only takes care about the part of the URL which is before the hash, and Angular takes care of the rest.
I´ve read some articles that explain how to remove the hash from URL. But if I remove the hash(#) from URL: Which routing works first?
OK, it is MVC. In that case we have to edit the MVC Route in order the server to understand the URL. But we are at the beginning again. Does it make any sense to use Angular Routing and MVC together ? Is not enough with MVC Routing?
Maybe I´m missing something. I hope you can help me.
Does it make any sense to use Angular Routing and MVC together ? Is
not enough with MVC Routing?
TL;DR;
I've rarely use both. The only time I use both is when I need to authenticate the user for some routes.
Long answer
1. Authentication
As you already figured out, Angular routing is great when you want to navigate to another page without the roundtrip to the server. It's usually a SPA. But there might be a scenario when you need to authenticate the user before sending the HTML, then MVC routing will be handy. I wrote an answer about it here. Note the difference between sending HTML and sending DATA to to the client. If you have no server routes the html-pages (or templates) will be fully accessible (unless you limit access in web.config or some other way). Some times the HTML-pages can contain some sensitive information as well...
The most common scenario is if you have a public site with an admin-part. But in my experience you can handle this on client side with client-side-routing only. It's usually the data that is sensitive, not the templates.
2. Server-side logging
The other scenario is when you want to do some logging on server side. For example if you want to log every page request. This can often be done on the client as well... Look at Google Analytics. But you might want to log the request even if the browser has javascript turned off.
3. SEO
There might be some SEO-issues when using client-side-routing. But this is only when we render the html with client side templates and if we compare to completely rendered views with MVC.Net. Do not confuse me posting the link with me actually agreeing with the content...
4. WCAG
In my country all government sites need to follow WCAG. One of the rules are - no javascript. Or at least that the site should be fully accessible without javascript. Without javascript client-side-routes are simply very difficult. ;)
These are some examples when you might need both server-side and client-side routes. But to sum up, in most cases client-side is enough.
URLs shall be without hashbang
It shall fall back for older Browsers which don't support the History API
Using Angular or Ember
Question: Is there a need to use the history.js?
If yes, read on.
On teamwork.com or soundcloud or other modern websites there is a mechanism to have links loading just a part of the website and at the same time, the URL changes (there is no hashbang). I want to implement this as well and also want to support older browsers and read that history.js can do this. Here is a related question to this where I found that this uses the History Api.
At the same time I want to uses Angular or Ember. I know they have their own routing and there is for example a tutorial to remove the # here.
I read that the different browsers handle the history api differently and that the history.js is a way how to tackle this issue.
So is there a way how to combine those front-end frameworks with that api? I'd start somewhere in the routing but get stuck thinking about what to do...
A new implementation should have cross-browser compatibility including handling older browsers. On one hand I want to have a front end framework to separate front from the backend, not sure about which one to use, yet. On the other hand I like how i.e. teamwork.com handle links that they only load a part of a page (including an animation) when you click on it. At the same time the URL changes and if you type a URL directly the page is loaded correctly. It seems that they do it with jQuery.. not quite sure.
Anyone knows how to use both, routing and the history.js?
I would just use AngularJS with UI Router. It combines routing with history.js like features. It has a HTML5 mode which you can enable which will allow pages to update via AJAX without the use of a hash #.
It should automatically cope with older browsers and change the URL format accordingly.
I have Backbone working with pushState. It's very nice, but now I understand that I should support loading the app from any route that backbone uses. For example, if somebody enters a backboen route manually to their browser, the server should respond to that and render the page and then let backbone take over.
What I am wondering, is what is the most efficient way to handle it? Backbone recommends also bootstrapping data on initial page load to reduce ajax requests. Should I only try to bootstrap data that is necessary for that particular view or should I try to bootstrap basic collections (for example: users, settings, documents, etc)?
For the first part of your question, you could just specify a callback route (which matches everything and gives the homepage) so the user never gets a 404 (don't use that when developing the app though, it could give you some hard times debugging it if you have a real 404 when making a call to the server).
For the second one, I'd say it depends on the amounts of data you need. I'm personally developing a modular application, and unfortunately can't really bootstrap anything. I'd say it's just some advice.
I've been trying to get various routes bookmarkable within my app, and this is possible if I don't have pushState enabled. A user can enter mysite.com/#/view/30 and the proper view renders.
However, if I were to enable pushState and go to mysite.com/view/30 I receive a parse error (navigating there via the root page works fine).
I'm currently utilizing the Backbone.js Boilerplate using Require.js, and the parse error is appearing in my config.js file. I'm fairly certain the issue isn't with Require but I'm not completely sure. Frankly, I don't necessarily know what code to paste here either because I believe I'm more lacking a fundamental understanding a difference between hashbangs vs. pushState.
I've read up on the HTML5 feature, however the answer to my specific question still eludes me.
The page with your Backbone router on does not exist at the path you are pointing to in your pushState. The pushState is purely to change the URL representation. You'd have to do some server config changes to route all of your requests back to a main index file.