React router 6 NavLink show active with trailing slash - react-router-dom

In React Router v6, I want a <NavLink> to show as active when the current route does or doesn't include a trailing slash. So the following should display as active when the route is /foo, or /foo/, but not /foo/bar. Is that possible?
<NavLink end to="/foo">
...
</NavLink>

Related

How to redirect to URL with trailing slash in warp?

I am using warp to serve a directory of static files. Unfortunately the relative links used in those static files can only be resolved, when I add a trailing slash to my path.
This is the code I use to serve the directory:
let route = warp::path("segment")
.and(warp::path("another"))
.and(warp::fs::dir("../path/to/static/files/folder"));
warp::serve(route).run(([0, 0, 0, 0], 3030)).await;
So now
0.0.0.0:3030/segment/another/ works fine
0.0.0.0:3030/segment/another does not work
In principle I would not mind this and just always use the URLs with trailing slashes, however when I "Add to Homescreen" the page from Safari on iOS (as a PWA) the trailing slash is ommited automatically.
So in order to work around this, I tried to create a redirect, and then add the trailing slash like this:
let redirect = warp::path("segment").and(warp::path("another")).and(warp::path::end())
.map(|| {
warp::redirect(Uri::from_static("0.0.0.0:3030/segment/another/"))
});
however this redirect filter only matches 0.0.0.0:3030/segment/another/. When I omit the warp::path::end() the redirect works for 0.0.0.0:3030/segment/another but now everything (for example 0.0.0.0:3030/segment/another/styles.css) gets redirected to 0.0.0.0:3030/segment/another/.
Is there a way to only redirect when the path does not end with a slash or a file extension (e.g. .html, .cssetc.)?
It might be that my overall aproach is incorrect here, too.

React Router v4 URL issue

Ours react app works in dev mode (localhost) perfectly, but when we put it onto the Heroku server we cannot access routes directly. When we do history.push({ }) to our path we get a 404 page.
You can see the page here: placemate.herokuapp.com
Steps to reproduce: go to the above URL, see it load. Then add /login to the URL bar and you will see that a 404 page appears. However, clicking a login from the header will direct you properly.
Here is our router code:
import React from 'react'
import { Switch, Route, Redirect } from 'react-router-dom'
import '../../App.css'
import Home from '../../scenes/general/home/Home'
import Login from '../../scenes/general/login/Login'
import Register from '../../scenes/general/register/Register'
import GuestHeader from '../../components/general/header/Header'
const Main = () => (
<main className='main_app'>
<GuestHeader />
<Switch>
<Route exact path='/' component={Home}/>
<Route path='/login' component={Login}/>
<Route path='/register' component={Register}/>
</Switch>
</main>
);
export default Main;
index.js file:
ReactDOM.render(<BrowserRouter><App /></BrowserRouter>, document.getElementById('root'));
registerServiceWorker();
Why 404 Not Found
This is because when you put up any path in your address bar its request is sent to the web server not react. As you know the react-router we are using is responsible to display the correct component based on the route, but since you pass the route to nginx / apache server not react-router; hence your web server tries to find www.example.com/login which actually does not exist. Hence you get 404 not found.
Solution
Try to create a .htaccess file on your web server public HTML root directory. Create some rules so that the request is always forwarded from the root path. This will let the react come into the picture, hence the react-router can grab the path and render the appropriate component.
For example, you can create something like this
For Apache server
RewriteEngine On
# If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
#RewriteCond %{SERVER_PORT} 80
#RewriteRule ^(.*)$ https://www.example.com/$1 [R,L]
RewriteRule ^ - [L]
# If the requested resource doesn't exist the serve index.html
RewriteRule ^ ./index.html
For Node.js
Sample code for node.js express server can be like this (present in file for server implementation, conventionally named as server.js)
const express = require('express');
const path = require('path');
const app = express();
if(process.env.NODE_ENV!== 'production'){
//do something if you are in development environment
//below lines only if you are using webpack based deployment
const webpackMiddleware = require('webpack-dev-middleware');
const webpack = require('webpack');
const webpackConfig = require('./webpack.config.js');
app.use(webpackMiddleware(webpack(webpackConfig)));
}
else{
// in production env do following thing
app.use(express.static('public_html_folder'));//give user access to public assets
//redirect all request to index.html for compatibality with react router
app.get('*',(req,res)=>{
res.sendFile(path.join(__dirname,'public_html_folder/index.html'));
});
}
app.listen(process.env.PORT || 3050, () => console.log('Listening'));
I hope this solves your problem or at least give you an idea of what to do if there is a different backend server.

Routes in express JS

I have a code line:
app.use(express.static('public'));
for static files in public folder, but build a route:
app.get('/search/jobs', jobs.index);
The Expressjs is putting /search before url.
And I'm a getting error in console browser:
GET: http://localhost:5000/search/css/materialize.css
Any idea?
You need to use absolute paths in your html/css (e.g. /css/materialize.css). With relative paths (e.g. css/materialize.css) the browser will look up the path relative to the current path/"directory" (/search in this case).

Snap framework root ("/") route not being handed?

I have added routes to my app in the following format:
addRoutes
[ ("/", redirect "/docs/home")
, ... more routes
]
But for some reason the root handler is being ignored altogether. What is happening here?
It turns out that if you have an index.tpl file then the SnapFramework will ignore any "/" mappings and go straight to that instead. To fix the problem I just ran:
git rm snaplets/heist/templates/index.tpl
And then reloaded my templates and the route on root started working.
(I could not find that anywhere in the docs so I decided to post that here)
Edit: I later discovered (with help) that the problem was that I was adding my routes AFTER I ran heistInit. If i added my routes before heistInit then there was no problem.

Cannot serve static files with express routing and no trailing slash

I want a route called 'main' which will serve static files:
app.use('/main',express.static(__dirname+'/public'));
However when i do:
http://my.site.dev/main
The CSS and JS files won't download because it is trying to get them from
http://my.site.dev/css/styles.css
It should be getting the files from:
http://my.site.dev/main/css/styles.css
However, if I access my site with a trailing slash:
http://my.site.dev/main/
All files come through fine
Any ideas why not having a trailing slash messes up resources like CSS and JS from coming in?
This is an http problem, not just an Express-related challenge. The problem is discussed at:
Relative URLs and trailing slashes
http://www.bizcoder.com/the-mystery-of-the-trailing-slash-and-the-relative-url
If your URL is /main and your relative URL is css/style.css, it will resolve to /css/style.css; but if your URL is /main/, the relative URL resolves to /main/css/style.css.
My strategy for dealing with this is to redirect to add the trailing slash. Like this in Express:
app.all(/^\/main$/, function(req, res) { res.redirect('/main/'); });
app.use('/main/',express.static(__dirname+'/public'));
Or:
app.enable('strict routing');
app.all('/main', function(req, res) { res.redirect('/main/'); });
app.use('/main/',express.static(__dirname+'/public'));
How are the JS/CSS files requested in the HTML? If you're using strings like css/styles.css, then it will try to get them from the current directory. The directory for /main is / (just like /main.html would be), while the one for /main/ is /main/. A quick fix would be to use /main/css/styles.css in your HTML.

Resources