1
votes

I have a React app on front end. Here is the routes:

    var React = require("react");
    var ReactDOM = require("react-dom");
    var {Route, Router, IndexRoute, browserHistory} = require("react-router");
    var Main = require("Main");
    var BlogList = require('BlogList');
    var Blogpost = require('Blogpost');
    var NewBlog = require('NewBlog');
    var EditBlog = require('EditBlog');
    var NotFound404 = require('NotFound404');


    ReactDOM.render(    
        <Router history={browserHistory}>   
            <Route path="/" component={Main}>
                <IndexRoute component={BlogList} />     
                <Route path="blogs/new" component={NewBlog} />          
                <Route path="blogs/:id/edit" component={EditBlog} />                        
                <Route path="blogs/:id" component={Blogpost} /> 
                <Route path='404' component={NotFound404} />
                <Route path='*' component={NotFound404} />          
            </Route>        
        </Router>, 

        document.getElementById("app")
    );

and here is index.html from public directory:

    <!DOCTYPE html>
    <html>
    <head>
        <script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>     
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">        
        <link rel="stylesheet" type="text/css" href="./stylesheets/app.css">
        <title>MERN Blog</title>
    </head> 
    <body>  
        <div id="app"></div>
        <script src="bundle.js"></script>   
    </body>
    </html>

My express backend:

app.use(express.static(__dirname + '/public'));

.....

//index route
app.get("/api/blogs", function(request, response){      
...
});
//show route
app.get("/api/blogs/:id", function(request, response){      
...
});

app.get('*', function (request, response){  
    response.sendFile(path.resolve(__dirname, 'public', 'index.html'))
});

All works fine when I click links - all renders correct. But when I refresh the same page - I got blank page. My index.html loads some files - bundle.js etc. And those requests are handled by "*" route from backend - and index.html is alwas returned.


How to make static files handled properly?

1
Try putting everything else (like images, css...) under a static path... like /static and create a route to that, so the browser can find those resourcesLucas Katayama
Is the issue that static files aren't showing up or that when you refresh a route it doesn't show up correctly?BradByte
@BradBumbalough - the problem is - when I load index.html - it makes requests to my backend for bundle.js file. It must be handled by app.use(express.static(__dirname + '/public')); but instead it's handled by app.get('*' ...kurumkan
@LucasKatayama I get your idea. Thank you. It could be considered as a solution I think. But for what I am using app.use(express.static(__dirname + '/public')); So it means I dont need it anymore?kurumkan
Oh NOW I get the problem... your are using relative paths... when you calll ./stylesheets/ when you refresh a page inside say /react-route/X.... it will call /react-router/X/stylesheet.... Try using absolute path so it can be handled by express.staticLucas Katayama

1 Answers

5
votes

Try using absolute paths in the index.html

<!DOCTYPE html>
<html>

<head>
    <script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
    <link rel="stylesheet" type="text/css" href="./stylesheets/app.css">
    <title>MERN Blog</title>
</head>

<body>
    <div id="app"></div>
    <script src="bundle.js"></script>
</body>

</html>

The problem using relative paths and browserHistory occurs when you refresh a page in path like /route/x/y/z and it loads index.html then it tries to load relative css (for instance) /route/x/y/z/stylesheets/app.css

When you use absolute paths it will be handled by your express.static

app.use(express.static(__dirname + '/public'));

It will load index.html and tries to load /stylesheets/app.css which will be handled correctly... like this

...
<link rel="stylesheet" type="text/css" href="/stylesheets/app.css">
...
<script src="/bundle.js"></script>