I have a react and django app which is being served behind nginx. The /admin route and /api routes both point to uwsgi. However when loading these routes the react app is served unless a hard refresh of the page is peformed. It seems like react is serving all routes instead of just the index.
Is there a way to exclude routes in react so it will only display if the path is "/" or is there something in nginx/django config I can change to overcome this issue.
This is a snippet from my nginx conf:
location / {
try_files $uri $uri/ =404;
}
location /api/ {
uwsgi_pass uwsgi;
include /etc/nginx/uwsgi_params;
}
location /admin/ {
uwsgi_pass uwsgi;
include /etc/nginx/uwsgi_params;
}
and my django urls config:
urlpatterns = [
path('admin/', admin.site.urls),
path('api/v1/', include(routers.urls))
]
Any ideas on how I could proceed would be appreciated
It sounds like React is intercepting the onClick event of the links and preventing the browser from handling it normally.
You can try altering the link tags so that they prevent React from doing that:
<a href="/admin/" onClick={() => { location.href = "/admin/" }}>Admin</a>
/* Or if using react router */
<Link to="/admin/" onClick={() => { location.href = "/admin/" }}>Admin</Link>
Is there a way to exclude routes in react so it will only display if the path is "/"…
How are the routes added or configured in React? They should be changed to use the format I illustrated above, or deleted if you don't want them to display at all.
… or is there something in nginx/django config I can change to overcome this issue.
Your nginx configuration is written correctly. You can test it here.
I think i found the solution.
1- update your react-scripts to ^v4
2- add urls you don't want to be cached to service-worker.js file:
registerRoute(
({ request, url }) => {
...
if (
url.pathname.startsWith('/admin') ||
url.pathname.startsWith('/api')
) {
return false;
}
...
return true;
},
createHandlerBoundToURL(process.env.PUBLIC_URL + '/index.html')
);
Related
I have a react and django app which is being served behind nginx. The /admin route and /api routes both point to uwsgi. However when loading these routes the react app is served unless a hard refresh of the page is peformed. It seems like react is serving all routes instead of just the index.
Is there a way to exclude routes in react so it will only display if the path is "/" or is there something in nginx/django config I can change to overcome this issue.
This is a snippet from my nginx conf:
location / {
try_files $uri $uri/ =404;
}
location /api/ {
uwsgi_pass uwsgi;
include /etc/nginx/uwsgi_params;
}
location /admin/ {
uwsgi_pass uwsgi;
include /etc/nginx/uwsgi_params;
}
and my django urls config:
urlpatterns = [
path('admin/', admin.site.urls),
path('api/v1/', include(routers.urls))
]
Any ideas on how I could proceed would be appreciated
It sounds like React is intercepting the onClick event of the links and preventing the browser from handling it normally.
You can try altering the link tags so that they prevent React from doing that:
<a href="/admin/" onClick={() => { location.href = "/admin/" }}>Admin</a>
/* Or if using react router */
<Link to="/admin/" onClick={() => { location.href = "/admin/" }}>Admin</Link>
Is there a way to exclude routes in react so it will only display if the path is "/"…
How are the routes added or configured in React? They should be changed to use the format I illustrated above, or deleted if you don't want them to display at all.
… or is there something in nginx/django config I can change to overcome this issue.
Your nginx configuration is written correctly. You can test it here.
I think i found the solution.
1- update your react-scripts to ^v4
2- add urls you don't want to be cached to service-worker.js file:
registerRoute(
({ request, url }) => {
...
if (
url.pathname.startsWith('/admin') ||
url.pathname.startsWith('/api')
) {
return false;
}
...
return true;
},
createHandlerBoundToURL(process.env.PUBLIC_URL + '/index.html')
);
I'm following this tutorial to make my React app (localhost:3000) communicate with Node server (localhost:5000) .. so instead of typing <Link to='localhost:5000/auth/google'>Login with Google</Link> I only want it to be just '/auth/google', but when I click on the button with Link tag it sends this error "No routes matched location "/auth/google"
I'm using React v17.0.2
this is what's inside my setupProxy.js file
const { createProxyMiddleware } = require("http-proxy-middleware");
module.exports = function (app) {
app.use(
["/auth/google", /api/*],
createProxyMiddleware({
target: "http://localhost:5000",
changeOrigin: true,
})
);
};
the weird thing though is that I got no error when I type the route directly in the browser (both ports work just fine) and it redirect me to the page I want (handled by Express)
If there's no solution for this problem for now, is there any other way to use a proxy in a MERN application because from what I know adding "proxy" in package.json is not working anymore
Context: I'm opening up my React dev environment to external hits using a paid version of the tool ngrok -- I am running WebPack 4.0 with a devServer.
I go to my app's main page:
https://my-example-domain.ngrok.io
Loads fine.
I click one of the links on my app's main page, The router works well and I see the content for:
https://my-example-domain.ngrok.io/my-sub-page
However, if I refresh at this point, ngrok gives out a 404:
Cannot GET /my-sub-page
The reason I suspect is that in a SPA, the internal app's URLs are processed by the front end in React-Router and externally, there is no resource called /my-sub-page
Is there a way to force this to work?
The problem is that the local server doesn't know about your spa routes(react-router). To fix this, you have to create a simple server that will serve your static build and have a fallback route that will enable spa-routing.
Example in express.js:
import express from 'express';
import path from 'path';
// ... other imports
const app = express();
app.use(express.static('build'));
/*
... some route handlers
*/
// * Unknown endpoint
app.use("/*", (_req, res) => {
res.sendFile(path.join(__dirname, "../build/index.html"), (err) => {
if (err) {
res.status(500).send(err);
}
});
});
app.listen(process.env.PORT || 3000 , ()=>{
console.log('server running')
})
This resolved it -- in webpack.config.js
devServer: {
...
...
historyApiFallback: true, // <- inserting this resolved the issue.
}
I want to host the react app and laravel app in the same laravel application project.
The front end app is react and backend(admin panel) laravel.
I want redirect all request to specific front end view except first URL segment == backend/:any
Eg.
http://host.com/backend/(any)
Continue with laravel router
http://host.com/(any) except backend/
Continue with react router
Any idea for that matter?
You have two options here, either pass a regular expression to the any route to ignore API prefixed routes
Route::get('/{any}', function () {
return view('index.blade.php');
})->where('any', '^(?!backend).*$');
Route::fallback(function () {
return view('index.blade.php');
});
From the docs
Fallback Routes
Using the Route::fallback method, you may define a route that will be executed when no other route matches the incoming request. Typically, unhandled requests will automatically render a "404" page via your application's exception handler. However, since you may define the fallback route within your routes/web.php file, all middleware in the web middleware group will apply to the route. You are free to add additional middleware to this route as needed:
Route::fallback(function () {
//
});
The fallback route should always be the last route registered by your application.
Try something like this in the "routes/web.php":
// WRITE BACK-END ROUTES AT FIRST
Route::group([
'prefix' => 'backend',
], function () {
Route::get('/', 'AdminController#dashboard')->name('dashboard');
Route::get('admin-page-1', 'AdminController#page1')->name('page1');
Route::get('admin-page-2', 'AdminController#page2')->name('page2');
// some other admin routes if you need
});
// FRONT ROUTE(S)
Route::get('/{text}', 'FrontController#front')->name('front');
My Heroku app is using React with React Router. I use Switch to navigate through different components, so the URL changes as well (e.g. /room/4141). However, if I reload the page, it doesn't act like if it was a React app, but instead it searches for the mentioned .html file.
I used this Buildpack: https://github.com/mars/create-react-app-buildpack.git but it seems to do nothing in regards with pages being rewritten to index.html.
Is there a way to prevent this behaviour and rewrite all URLs to index.html?
**EDIT:
I'm not familiar enough with express, but here's how the index.html is served.
const express = require("../../node_modules/express");
const app = express();
const server = require("http").Server(app);
const io = module.exports.io = require('../../node_modules/socket.io/lib')(server)
const path = require("path")
app.use(express.static(path.join(__dirname, '../../build')));
if(process.env.NODE_ENV === 'production') {
app.use(express.static(path.join(__dirname, '../../build')));
console.log("DEBUG HERE", __dirname, path.join(__dirname+'../../build'));
//
app.get('/*', (req, res) => {
res.sendFile(path.join(__dirname+'../../build/index.html'));
})
}
//build mode
app.get('/*', (req, res) => {
res.sendFile(path.join(__dirname+'../../public/index.html'));
})
That buildpack can be configured via a JSON file:
You can configure different options for your static application by writing a static.json in the root folder of your application.
One of the sample routing configurations looks like it does exactly what you want:
When serving a single page app, it's useful to support wildcard URLs that serves the index.html file, while also continuing to serve JS and CSS files correctly. Route ordering allows you to do both:
{
"routes": {
"/assets/*": "/assets/",
"/**": "index.html"
}
}