Dynamic URL routes for Static site in Vue - javascript

I have a static site, there is no way to add in re-writes via htaccess or similar which is how would normally approach this functionality. We're running the site with Vue, on top of static .html templates eg
\example\index.html
So I can visit www.mywebsite.com/example/ and it'll load the page, and run Vue, when I want a subpage, based on this layout, I currently have to create
\example\subpage\index.html
Again this works great www.mywebsite.com/example/subpage/, but what I'm wanting is to pull data in via an API feed, and be able to have dynamic URLs
\example\subpage\any-page-name-here
The closest I've found is to use # so
\example\subpage#any-page-name-here
Which allows Vue to pick up the data after the # and query the API with that.
Any help would be greatly appreciated, there's no work around for the limitations of the hosting, so I need a Vue/JS/HTML only soltion.
Thanks!

As you cannot change the web server configuration, the only possibilities are the hashtag option or the query string e.g
example.com/site/?dynamic-data
The reason is the web server decides what to do with the request in the first instance, and without any configuration it will simply load a page if it exists or show a 404. This happens before your Vue app is invoked.

Related

VueJS: Redirecting URL to SPA Routing

I am currently working the first time with vue-router and I am wondering if there is a way to handle redirecting through vue or if there are other options in a node.js environment to do so.
For example, if someone wants to visit my site through typing the URL
example.com/contact
he will currently get to
example.com/contact#/home
But of course I want to redirect to the correct path.
You have two options.
The first one is to keep using hash router, which means that you will have to add a hashtag before the path so the correct url would be example.com#/contact. Hash router has the benefit that it works with your web server out of the box without any other configuration.
Another option is to switch to history mode on the Vue router. History mode lets you have URLs without the hashtag, however there's a drawback that it doesn't work with most web servers without separate configuration. The link above includes the necessary configurations for many web servers, where you will need to add it somewhere depending on the web server.

How to simply add pages without bogging down routes? (express.js)

I am working on a site with Express.js, and like it very much. I have it operating stably, but would like users to be able to add pages to the site (via a form, where it will have set fields, or via uploading a jade file). Preferably I would also like a moderation queue. Failing this, how can I add pages without having to add an entry to index.js for the route every time? If I add lots of pages, won't this make it slow?
Sorry for the wall of questions, and thanks in advance for any help!
EDIT: It's been requested that I narrow the query, so here goes:
I would like to add a web interface to Express.js that allows users to fill in a form and add a page to the website under a certain path. I would like a sort of "moderation queue" where I approve pages before they go live. I cannot find any sort of information on this use case. How do I do it? Thanks.
First and foremost, you will need to get yourself a database where the moderation queue can sit and wait to be processed. The specific methodology of how to structure this database, and how to integrate this data into pages that can be delivered will depend on your choice of database and view engine.
After you have set up this system, you can use express's route parameters so that you do not have to write out all the possible routes into your scripts. Your express app can take the route parameters, look up the relevant data in your database, integrate this into a page using your view engine, and have express deliver this page to your client.
I would recommend giving express's guide on routing a thorough read as well as doing some more research into databases, and view engines.

can local storage store the whole page

so I have seen a lot of people using local storage to store certain parts of a web page but not an entire web page is it possible? , if so how? , if not is there a way to store an entire web pages data so the user can come back to it how they left it?
This can be done if you use javascript to save document.body.innerHTML into the webstorage and you use javascript to load it back from the storage when the page is loaded next time. If the web page is not in the webstorage, you could redirect the user to the web page.
But this depends on the design of your web page and if there is session index etc in the body of the web page.
You should also think of some way to handle versions. You dont want your users only use the cached version of your web page, but it should be updated once you update your web page.
The session storage is ~5mbit, so you cant save very much, especially not pictures.
Since LocalStorage allows you to store about 5MB~ you can store a full webpage there and then just call it into a document.write().
The following code does it:
Storing it:
var HTML = ""; //html of the page goes here
localStorage.setItem("content", HTML);
Retrieving it:
document.write(localStorage['content']);
Although this is possible it is common practice you only save settings and load them up into the right elements rather than the entire web page.
This is not really answering your question, but, if you are only curious how this can be done and don't need to have wide browser support, I suggest you look into Service Workers, as making websites offline is something that they solve very well.
One of their many capabilities is that they can act as a proxy for any request your website makes, and respond with locally saved data, instead of going to the server.
This allows you to write your application code exactly the same way as you would normally, with the exception of initializing the ServiceWorker (this is done only once)
https://developers.google.com/web/fundamentals/getting-started/primers/service-workers
https://jakearchibald.github.io/isserviceworkerready/
Local storage it's actually just an endpoint: has an IP address and can be accessed from the web.
First of all, you need to make sure that you're DNS service points on your Index page.
For example, if your Local-storage's ip is 10.10.10.10 and the files on that local-storage is organized like:
contants:
pages:
index.html
page2.html
images:
welcome.png
So you can point your DNS like:
10.10.10.10/index -> /contants/pages/index.html
In most of the web frameworks (web framework it's a library that provide built in tools that enable you to build your web site with more functionality and more easily) their is a built in module called 'route' that provide more functionality like this.
In that way, from you index.html file you can import the entire web site, for example:
and in your routes you define for example:
For all the files with the .html extension, route to -> 10.10.10.10/contants/pages/
For all the files with the .png/.jpg extension, route to -> 10.10.10.10/contants/images/
Local storage is usually for storing key and value pairs, storing a whole page will be a ridiculous idea. Try instead a Ajax call which Returns an partial view. Use that for the purpose of manipulation in DOM

Angular.js and SEO

I'd like to create a site with Angular (I'm new), but also want to be able to have different "views" be cachable in the search engines and have their own URL routes. How would I achieve this with Angular, or is best not to use it?
Enable pushState in Angular with $locationProvider.html5Mode(true); so that you have real URLs and make sure that, when the URL is requested by the client, you deliver the complete page for that URL from the server (and not a set of empty templates that you populate with JS).
When a link is followed, you'll go through an Angular view and update the existing DOM (while changing the URL with pushState) but the initial load should be a complete page.
This does mean duplicating effort (you need client and server side versions of the code for building each page). Isomorphic JS is popular for dealing with that issue.
If you want to expose Angular views to search engines and other bots, I suggest using an open source framework that we developed at Say Media. It uses node.js to render the pages on the server when it detects a bot vs a real user. You can find it here:
https://github.com/saymedia/angularjs-server
I would suggest not using different routes, however, as most search engines will penalize you for having duplicate content on multiple urls. And while you might think they would just hit the bot version of your site, they are getting more sophisticated about crawling single page app like sites. I would be cautious about duplicate routes for the same content.
Good Luck!

Backbone routers and compatibility with web server controller

How do I get compatibility between my web server's controllers and Backbone router?
I have it set it so when a user clicks on a link, a view is rendered, and the URL looks like this: /test/1, which is what I want. The problem comes in when the user tries to access test/1 by entering it into the address bar. My backend has controllers that is in charge of routing URLS.
How would I get it so it uses the Backbone routes rather than the backend routes?
One way that works is when I access the url #test/1. It is bookmarkable and can be entered into the address bar. The problem is that backbone stripes the # on load.
So, I see two solutions to my problem:
Get the backend controllers to interact with Backbone routes
Make it so the #'s aren't removed when they are entered inside of the address bar.
Which of the above solutions is recommended. And, how would I implement them. The second solution seems easier, but how would I make it so backbone doesn't strip the URLs of the hashes?
From what I understand when the user navigates to the root page and then test/1 via a link the logic is handled by backbone and a view is rendered. But when the user navigates directly to test/1 this is not handled correctly.
To handle this you need to setup a route on your server that points any URLs handled by backbone to the root page. The logic for this depends on your server which you have not specified. To do something like this in ASP you might setup a route like this:
RouteTable.Routes.MapWebPageRoute("test/{id}", "~/Default.cshtml", new {}, new { id = "\\d+" });
This would cause a URL such as test/1 to be handled by the default page which be the same handler as if the user navigated to /. Once the page has loaded on the client the Backbone router would fire for the test/1 route.
Well, really, there are many reasons why you want the URL to include the # all the time. It makes lots of things work better. For example, the correct controller is automatically selected by the web server and the correct route is automatically provided to Backbone whether you manually type in the URL, use a bookmark, use a link from another site, or use the back and forward buttons on the web browser. So choice 2 is definitely the one you want. This is also the standard behavior of Backbone.
So my question is "How did you get backbone to stop using the # in the first place?"
Edit: Thanks to Chris Herring for pointing us to a great article explaining why # is bad. With that, I will leave it as an exercise to the reader about which kind of pain they want to endure. I think # is still the way to go so long as all the Backbone route is changing is how the information on the page is displayed and not what information is on the page. If a web crawler that does not support JavaScript can scrape all the same information regardless of what comes after the #, then I still don't see a problem with it.

Categories

Resources