React router capturing too many paths - react-router

I used create-react-app to bootstrap my project.
I added react-router to my react app. After I build and serve using serve -s build, when I go to any path such as http://localhost:5000/favicon.ico, it takes me to my index, which means the URL change is being captured by react-router. However once I'm there, if I force reload the page with CMD+SHIFT+R then the static file loads as expected. How do I make this behavior the default?

According to the FAQ, when a site is served statically it needs to use HashRouter instead of BrowserRouter
https://github.com/ReactTraining/react-router/blob/master/FAQ.md
I also had to disable the service worker by commenting out two lines in src/index.js since it was caching everything all the time.
Making that change fixed my problem!

Related

How to host multiple versions of a SPA

I would like to host multiple versions of a SPA on the same site. I would like to use initial load paths like this:
http://host/myapp/1.0.1
http://host/myapp/1.0.2
However, if my html uses relative paths like "css/myapp.css", then these resolve to:
http://host/myapp/css/myapp.css
I know why this is, and I know if I use trailing "/" on the initial page loads it will work correctly, but obviously it would nice to not have to tell people to use the "/" on the end.
I suppose I could have the app adjust the base path on load, but that complicates the app somewhat. I am using vue and the solution would need to work at runtime, not compile time since i don't know all the subfolders the immutable app will be loaded from.
Is there a cleaner way to support multiple version-folders this way and have relative paths work properly?

react router changes base path on refresh

I am using react router v4. I noticed the same problem in v2 as well:
If I am at some route
/admin/details
and I do a page refresh, the root path of my app is changed to /admin. So any static assets loaded in index.html are missing because /admin is appended to the root path.
Same thing goes for api requests. If i want to make a relative API request from a nested route component, it breaks because rather than calling for example a get('data/images') it would doget('admin/data/images').
Any way around this? I've googled all day and nobody seems to run into this problem, the only answer is absolute paths for the requests.
I figured it out. I was calling my endpoint with a relative path ie I did
get('data/all') instead of get('/data/all') ...same thing with my scripts in the html. I just made them absolute and its all working. Sillyness.

Hiding page names in the browser

When we launch a website, we usually see webpage name (menu.php or admin.aspx) but I would like to hide that name and show only virtual path or just website name. I don't want it for the first page because I did that with default.aspx but I want to implement it for the whole website.
Showing www.abcd.com/faq/ instead of www.abcd.com/faq/faq.html
Note: My code is not MVC code and server is Apache.
Use .htaccess to rewrite the URL. Millions of tutorials are out there for that ;)
What you are asking is achieved using (for xampp, wamp, lamp or any other apache powered webserver setup) htaccess rewriterules. The rules take the URL and break it into parts that can be modified or used as variables to feed other pages - whilst still keeping the URL you typed. Neat huh!
Showing www.abcd.com/faq/ instead of www.abcd.com/faq/faq.html
call the file placed into the folder faq simply index.html (not faq.html) and then www.abcd.com/faq/
will display the page without the filename. (Make sure, you have defined index.html as a valid Directory index.)
There are more options with using mod_rewrite etc - but since you seem to use a prety static directory based navigation layout, that would be the easiest way.

Relative URLs in HTML when routing some subset of requests through nodejs middleware

Ok, so the title tells very little of my issue.
Basically, I have a project written in node that does something. It's a website that uses express, jade and stylus. I have set up the routing for static content like this:
app.use(express.static('public'));
The website works fine and all the CSS loads properly if, in the HTML, I reference it like this (for example):
link(rel="stylesheet", href="global.css")
As expected, when I hover over the link in Chrome's element viewer, the URL is localhost/global.css
So now I've got a couple of these little project and I want to put them all together. They aren't related but I'd like to put them all on my website. For this I have made a new project that server like a hub for the other ones.
In it, I've setup routing like this:
var proj = require("../proj/server.js");
app.use("/proj ", proj);
and in each of the projects I have set the modules exports like this module.exports = app where app is their respective express app object.
This also worked like a charm. I didn't have to run a separate server instance on a separate port for each project. Instead, you can access them like localhost/proj/
Now here's where the issue starts. The CSS that is referenced in the generated HTML of each project doesn't point to localhost/proj/global.css. Instead it still points to localhost/global.css. And since there's no global.css in the public folder of my hub application, it doesn't find it.
I could, of course, just change the relative URLs to proj/global.css instead of just global.css and this does work, but it means that I need to modify all of my projects. It also means that I have one more string to change should I decide to change their names.
Besides, the URL already shows localhost/proj, so why can't it just be automatically implied that when I reference global.css it should be looked for in localhost/proj/global.css?
I'm sure there's some easy trick I'm missing. Maybe my relative URLs should have some extra stuff that says it refers to the current URL?
Edit:
It actually seems that the relative URLs work, but only if the address in the address bar is localhost/proj/. If it's localhost/proj it doesn't. What can I do to force that last slash?
I don't know if it can help you, but in express, you can define several "public" directories
router.use(express.static(path.resolve(__dirname, 'client')));
router.use(express.static(path.resolve(__dirname, 'public')));
router.use(express.static(path.resolve(__dirname, 'foo')));

How to get rid of .html extension when serving webpages with node.js?

I am a beginner with node.js and am using express with the ejs layout, and I want to know how to get rid of the .html extension when putting up a page. For example if I go to my localhost:3000/about.html - that works but I want it to show up as just /about. Also, having trouble figuring out how to change the favicon if anyone knows how to quickly change that from the express default.
Any help would be great thanks.
(I realise this question is old, but it appears high in Google search results, and the accepted answer isn't the best solution.)
The best solution for serving up static content in express.js is express.static. To avoid having to specify file extensions in URLs you can configure it with a list of default file extensions that it will use when searching for static files:
app.use(express.static(pathToBaseFolderOfStaticContent, {
extensions: ['html', 'htm'],
... // Other options here
}));
This will serve up pathToBaseFolderOfStaticContent/somePage.html or pathToBaseFolderOfStaticContent/somePage.htm in response to a GET request to http://www.example.com/somePage, which is what you want. For example, if you visit https://arcade.ly/star-castle, the file it serves up is just a static file called star-castle.html. I haven't had to add any special routing for this, or any other static file - it's all just handled by express.static.
I only need to add specific routes for content that requires active work on the server to return. A big advantage here is that I can use a CDN to cache more of my content (or nginx if I were running an internal line of business app), thus reducing load on my server.
You can obviously configure as many default file extensions as you like, although I'd tend to keep the list short. I only use it for resources where the URL is likely to appear in the address bar, which generally means HTML files, although not always.
Have a look at the following documentation on serving static content with express.js:
http://expressjs.com/en/starter/static-files.html
http://expressjs.com/en/4x/api.html (the express.static documentation is at the top)
This is also answered at In express what is the common way to associate a default file extension with static content requests?.
The favicon.ico issue can be solved by dropping your favicon into the root folder from which you serve static content, as well as implementing +Costa's solution where you reference it using a <link> in the <head> of your documents.
In theory you shouldn't need to do put the favicon in the root folder but, in practice, some browsers will still ask for it from the site root even though it's referenced in the <head> of your document. This leads to a spurious 404 error that you'll be able to see in client side debugging tools (e.g., Chrome dev tools).
The Favicon issue is usually a caching problem. As long as you have this code in your base html layout:
<link rel="shortcut icon" type="image/x-icon" href="/images/favicon.ico">
Then just navigate to wherever that image is with your browser, and that should force your cache to update.
I figured it out. I looked at this post Render basic HTML view? which solved the problem I was having.
app.engine('html', require('ejs').renderFile);
app.get('/', function(req, res){
res.render("index.html");
});
And this all goes in the app.js or whatever file you are running.