I am trying to implement a javascript router with window.history API. I've been using ui-router for a long time but I want to create my own router for my smaller apps. Everything looks fine until meeting a problem like this: I am serving my page at localhost:8080/index.html. I am routing in the page with history API related properties. When I click to a route, I lose the index.html part. For example url becomes localhost:8080/home. When I directly try to go to that state, as you expect I get 404 error naturally. How can force to route over index.html to that state?
HTML5 history (pushState, etc) works by rewriting the URL on the client side. Hence it needs the server to also be able to rewrite the URL, and load the same index.html file whatever the URL.
Without this server rewrite, the two possible options are :
Use a hashbang JavaScript router based on URL like /idex.html#!/current/path
Do not use JavaScript for routing, and just rely on server directory structure to serve different file for each endpoint
Related
I am trying to make a Single Page Application using html, css and javascript. I would like to add some routing to it. I have made server-side rendered websites with nodejs and express. How do I create a routing system for my SPA? Can we use express for client-side routing? If not, are there any alternatives to express for client side routing?
If you don't want to use a framework/library for building a SPA, you have two options
Use a JS routing library ex: navigo, didn't try it myself TBH
Build it by yourself
To build your own simple SPA Routing, first, you need to:
Define routing config, each path with the relevant component/element/content to load
Define your routing root, the element where you will inject the content
Then you have two options:
Use # Hash paths (ex: domain.com/#/messages) with window popstate event, so you can handle this event by getting the hash path and decide which content to inject in the root, check this answer for more details about his approach
Implement a custom routing with normal paths (ex: domain.com/messages), that needs more effort, and to achieve that you need to:
Implement your custom navigation links, where you need to prevent the default behavior of navigation, and do the navigation manually using your custom logic
Use History API, (ex. pushState) to control the location state and the history stack
Adjust your server config to always load index.html
Add your custom logic using the Location API to manage these redirects manually, ie. when a user opens domain.com/messages, it will open index.html, then you need to check manually what the content to load for /messages path and inject it in the root element
Please be aware of the needed time, effort, reliability, maintainability, of each option before starting!
I am using react-router-dom in my react project.
I am trying to programmatically navigate to a new parameter using: history.push("/newparam")
But the problem is navigating like this, isn't refreshing my page. Looks like its doing fake client
side routing. But I want to refresh my browser when I am navigating programmatically.
So how can I do something like a server-side routing using react-router-dom, where the page will refresh when the site will change url?
When you use react-router the complete routing is handled by the react on client side, So the server is responsible to only load the index of the frontend application, This is a normal behavior in Single page application. We do all the communication with the server using XHR calls. Using history.push("/newparam") or <Link route='/newparam' /> is always going to load the page from client side.
I dont exactly know what your usecase, But if you want the page to reload every time you navigate to a new page, use html <a> tag, This will initiate server side rendering. The JS equivalent of this would be window.location.href = '/your-redirect-url';
Let me know what exactly is your use-case so that I can help you further
I have a working front-end single-page-application written in JS (ReactJS), and a working back-end in Phoenix (Elixir). Everything works out fine as long as navigation happens within the application. However, when I try to access a page in the SPA from the browser, I get a route error fired from Phoenix. For example:
no route found for GET /search (PhoenixApp.Router)
is what I get when I access http://localhost:4000/search from the browser.
When I access http://localhost:4000/search from the navigation inside the SPA, I get a working page from ReactJS.
So my question: How can I get ReactJS to get the page, rather than Phoenix?
The standard way to do this for Single-Page Applications is to serve the exact same thing on every GET route as you're serving on /. You can add a wildcard GET route to your Phoenix Router and point it to the same thing as the route for /. If / is served from PageController's index function, you should add:
get "/*anything", PageController, :index
I have a single page application - which means everything on the server gets redirected to a single index.html file which does the heavy lifting and routing using the HTML5 history api (pushstate).
Now, I want to add a new landing page to the side - let's call it landing.html and I want clients to first get to landing.html when they access / and index.html if they access any other route.
Now IE9 does not support the HTML5 history API, so using "hash urls" paths like /books/authors become /#!/books/authors in it. Since the hash section of the URL is not sent to the server as far as the server is concerned all paths are / which means I can't route to landing.html or index.html based on that logic.
I've thought of a hack - redirecting URLs with / to landing.html, detecting #! on the client, adding a cookie on the server (or client) called notReallyHomePage and redirecting to the correct page based on the cookie on the server. This is really hacky and not a good solution.
What would be the correct way to deal with routing in this case?
My backend is in ASP.NET MVC but I don't think that's relevant to the question
Hmmmmm... What's the content of landing.html? From its name I'm guessing it's a pretty simple page.
Couldn't you have its contents be a part of index.html and hide/show it according to the "first time user" logic?
Or if landing.html is some weird page created by your marketing or something, then place it in an iframe which hides/shows according to the same logic.
(obviously when you show landing.html then you hide index.html)
For rapid prototyping of my concepts, I'm using Express with Mongo and so far have set up a mongostore cookie storage system.
My question: Is it possible, after logging in/authenticating/etc, to have everything occur on the same page, aka '/game'? I still want multiple views and routes to be rendered, but using different areas of the screen, or overwriting elements on the screen, with the base game.jade still visible.
I essentially want to have the user on the same URL the entire time, but still use multiple routes and views. I looked into stuff like '/game/:stuff' but that still changes the URL I think.
FYI this is called a single-page web application.
One common way to do this is to route to different views using the hash token. For example, all of the following URLs would be part of the same page:
/game#introScreen
/game#level1
/game#level2
Your client code can respond to changes in the hash portion of the URL and change the display accordingly. The page does not reload and all your JavaScript code (and variable state) remains in place.
If you're using a framework like angularjs it can help do the routing for you.