How to serve SPA in one separate route in Express multipage app? - node.js

Let's say I have a blog and it's a normal Express multipage app. Now I would like to have a blog content manager as SPA with Vue.js.
I want to serve this app from a single route e.g. https://myapp/admin/dashboard
while the rest is a plain multipage express app (same server).
How to setup something like this in express and vue?

There are three possible strategies:
either you serve everything under a common path to the SPA with something like
app.get("/spa/*", spa);
app.get("/spa", spa);
In this case the client-side app will have to know its prefix because it will have to prefix all its links, ie it will have to send you to /spa when it wants to send you home. Both Vue and React Router support this via an option.
either you use URL fragments, ie hash links of the form /spa#sublink
In this case Express sees a single route:
app.get("/spa", spa);
The application doesn't need to know its prefix, you can relocate it, it always sends you to a relative link like href="#sublink. The downside is that you can't have multiple levels.
or you use query arguments like /spa?item=sublink
This is probably the worst way to do it, since it combines the downsides of all other methods
If you are not sure, the second method is probably the way to go - it doesn't require any special setup.

Related

How can I use react with a custom webserver?

I want to use React for a project I am working on, but I also want to use an API.
How can I do it?
I have tried to Google this and ask different people, but I have not got a response yet, so I thought I would ask here. I want to use express and maybe not use create-react-app (as it takes up a lot of storage).
Working on a custom server doesen't preclude the use of an API.
If you want fetch the API from the express server and inject it directly on react frontend you need to enable server side rendering (useful post) and pass the data collected as a props from the server (check this example).
Rather then you can build your react project (using even create-react-app) and build an express server who return the index.html on call.
Personally I prefer the first one solution.

How to remove "#" in svelte spa router?

I use svelte-spa-router npm module for the router of my svelte project.
When using this module it adds "#" in the URL in default to denote it is the spa router.
Such as "localhost:5000/#/app/.." I want to remove this "#" and make the router as the whole router such as "localhost:5000/app" Could anybody help me with this, please?
This is not possible with svelte-spa-router. This package is a hash-based router, and the "#" is key to how this type of router works. From the package docs:
With hash-based routing, navigation is possible thanks to storing the current view in the part of the URL after #, called "hash" or "fragment".
For example, if your SPA is in a static file called index.html, your URLs for navigating within the app look something like index.html#/profile, index.html#/book/42, etc. (The index.html part can usually be omitted for the index file, so you can just create URLs that look like http://example.com/#/profile).
When I created this component, other routers for Svelte 3 implemented navigation using the HTML5 history API. While those URLs look nicer (e.g. you can actually navigate to http://example.com/profile), they are not ideal for static Single Page Applications. In order for users to be able to share links or even just refresh the page, you are required to have a server on the backend processing the request, and building fully-static apps is much harder as a consequence.
Hash-based routing is simpler, works well even without a server, and it's generally better suited for static SPAs, especially when SEO isn't a concern, as is the case when the app requires authentication. Many popular apps use hash-based routing, including GMail!
If you want your URL to not have a "#", you will need to switch to a HTML5 history-based router such as svelte-routing or routify.

Can express.js handle front end routing like sammy.js

We are starting a project at work and we have used sammy.js with handlebars.js to handle the front end rendering. We are moving this new project to node and using express.js. Do we still need to use sammy.js for front end routing? We do not plan to use any front end framework currently.
Sammy.js is a routing framework designed for single page webapps. That is, Sammy is traditionally used for requests that will never leave your browser and are handled by a set of Javascript code running within it.
Express is used for server side routing, or in other words requests that hit your server. In this case, your server would render the page, then hand the rendered response back to the browser.
You can use both of them together, or use one over the other. The question you should really ask while architecting your app is whether your app is better off as a single page webapp or a multi-page app? For that, I'll refer you to this question: Single Page Application: advantages and disadvantages

Mostly static express app with one server side route

I have an application that I'm developing using express that is almost a purely static site, with the exception of two forms that are posted to the server (a contact form and a request form). The site has roughly 10 static pages and two server side routes to accept the form submission.
I started developing the front end of the application with jade, stylus, and coffeescript, using grunt as both a development server and a build tool to output a production ready version (concat, min, etc..) of all these static assets.
Now onto the two server side routes. I'm curious what peoples thoughts are on this situation, where the app contains 90% static HTML, with only one or two server side routes.
So far I've considered three options:
Option #1: Purely static HTML and "outsource" the two forms to someone like Wufoo
This would eliminate the need for express altogether in production. I could continue to use grunt to build the application. However, I don't like this approach since I wouldn't have total control over the form submission. Not to mention, the number of form submissions with a free account is limited.
Option #2: Purely server-side using express and Jade
I don't like this approach either since I would define 10 or so server side routes, all of which simply render a jade template. Isn't that overkill? My routes would be littered with app.get() calls that contain a single res.render() in the callback. Also, even though we're probably talking milliseconds, why include middleware on pages that don't require it?
Option #3: Mix of #1 and #2, using the express.static() middleware
For this option, I would use something like grunt-express. This is my favorite option, however it seems a little "dirty" to mix client and server side jade templates. What I mean by this is that the express app would have (two) server side routes that are responsible for rendering a jade template. Mixing this with a call to express.static() that points to a directory that contains static HTML files that have been compiled from jade seems a little "dirty" to me. I'm not sure why.
If I choose option #3, how would my grunt build script work? Preferably, I would like the build to output a dist/ folder which contained a production ready express app, including my tiny little app.js file.
Any thoughts are greatly appreciated!
Option #2
res.render(...) is very smart
It will not generate HTML again (if you do not change res.locals)
Beside that render has smart cache control, it will send "304 Not Modified" to browsers, instead of whole body.
Just use Option #2, and make sure browsers get 304 for static content. If you just a newbie to nodejs, make sure you start your node in 'production' mode, because jade is slow in 'development'.
You can render all the server side templates with something like
app.get('/:template', function (req, res) {
res.render(req.params.template);
});

Express & Backbone Integration

Ok, I am new to web dev and here's a stupid question. I have been through a few tutorials for node, express and backbone individually, but I can't seem to wrap my head around how they are integrated. Particularly, consider this use case:
Person X opens the browser, types in a URL and hits enter->Express responds to the request and sends some data back to the browser.
My question is, where does backbone come into the picture here ? I know it's a mvc framework to organize your JS code. But, I can't find a place in this use-case where the server/browser interacts with backbone. Only thing I can think of is that the backbone saving the route and serving the page the next time. But what about the first time ? It would be best if someone could explain to me how the request gets routed from client browser to express/backbone to browser again.
Also, am I correct in assuming response.send() or response.json() will send the result to backbone when model.fetch() is called ? I mean, is there no additional code required ? Being new to web dev, I'm quite not used to the idea of the framework 'taking care' of everything once you send the response back.
EDIT : Here's what I have understood so far. Feel free to correct me if I am wrong. When I access websites like gmail, the server first sends a big html file including backbone.js code in it. The backbone.js code listens for events like clicking on links in the html file and handles them if the links are defined in it routes(routes are always relative to current route, accessing a completely different route sends request to the server). So, if I click compose, my url remains the same because backbone handles the request. However, if I click Maps/News services in the bar above, the server handles the request.
There is no special integration between backbone and node.js.
If you use the standard backbone sync method then all you need to do is:
Use the static middleware in express to serve up your static html/js/... files.
Define RESTfule routes in express that conform to what backbone is expecting.
Backbone does indeed make an http call when you do model.fetch. You could look in Chome network tab to see where it's sending the request to and then implement that route in express.

Resources