How should I implement detecting mobile in my reactjs + express? I used mobile-detect to determine if mobile but first I implemented it with const md = new MobileDetect(window.navigator.userAgent)
but I remembered window
doesn't exist when it's server loaded. The example in express section should work because that's the only place I could access req
but how do I pass it in my react app to be used afterwards?
UPDATE
// app.js
...
import { routes } from './routes';
import { match, RouterContext } from 'react-router';
import { renderToString } from 'react-dom/server';
...
const app = express();
app.use(express.static('public'));
app.set('view engine', 'ejs');
app.get('*', (req, res) => {
// routes is our object of React routes defined above
match({ routes, location: req.url }, (err, redirectLocation, props) => {
if (err) { // something went badly wrong, so 500 with a message
res.status(500).send(err.message);
} else if (redirectLocation) { // we matched a ReactRouter redirect, so redirect from the server
res.redirect(302, redirectLocation.pathname + redirectLocation.search);
} else if (props) { // if we got props, that means we found a valid component to render for the given route
const reducer = combineReducers(reducers);
const store = applyMiddleware(...middlewares)(createStore)(reducer);
...
const server = http.createServer(app);
const port = process.env.PORT || 3003;
server.listen(port);
server.on('listening', () => {
console.log('Listening on ' + port);
});
// client-render.js
import { routes } from './routes';
import { Router, browserHistory } from 'react-router'
ReactDOM.render(
<Provider store={store}>
<Router onUpdate={() => {scrollTop(); handleNotifs(store)}} routes={routes} history={browserHistory} />
</Provider>,
document.getElementById('app')
);
// routes.js
import AppComponent from './components/app';
import IndexComponent from './components/index';
...
const routes = {
path: '',
component: AppComponent,
childRoutes: [{
path: '/',
component: IndexComponent,
name: 'home'
}, {...}]
}
I accomplished exactly what you are requiring by making my routes module become a function that takes the user-agent. It then simply returns an array or nested routes. Here's an example...
routes.js
module.exports = (userAgent) => {
const md = new MobileDetect(userAgent)
if (md) { // not sure on the syntax of MobileDetect?
return {
// return mobile routes
}
} else {
return {
// return desktop routes
}
}
}
app.js
app.get('*', (req, res) => {
match({ routes: routes(req.headers['user-agent']), location: req.url }, (err, redirectLocation, props) => {
// continue as normal
}
}
client-render.js
ReactDOM.render(
<Provider store={store}>
<Router onUpdate={() => {scrollTop(); handleNotifs(store)}} history={browserHistory}>
{routes(navigator.userAgent)}
</Router>
</Provider>,
document.getElementById('app')
);
On a side note, using this approach we are able to also pass in the auth cookie to the routes so the onEnter
methods can redirect if the route is behind login.
Hope this helps! BTW React-Router is the best!! I got to meet the creators in NYC and they're top notch.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With