I'm giving next.js a spin and I can't get the simplest setup to work.
Here's my setup:
Relevant libs:
- "react": "^16.2.0",
- "react-dom": "^16.2.0",
- "next": "^4.2.2",
- "express": "^4.16.2",
- "next-routes": "^1.2.0",
- "material-ui": "^0.20.0",
server.js
const express = require('express')
const next = require('next');
const routes = require('./routes');
const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handler = routes.getRequestHandler(app, ({req, res, route, query}) => {
render(req, res, route.page, query);
});
const server = express();
app.prepare()
.then(() => {
server.use(handler).listen(port, (err) => {
if (err) throw err
console.log(`> Ready on http://localhost:${port}`)
})
})
routes.js
const routes = module.exports = require('next-routes')();
routes
.add({name: 'walk', pattern: '/walk/:id'})
_document.js
import Document, { Head, Main, NextScript } from 'next/document';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
export default class extends Document {
static async getInitialProps(ctx) {
const props = await Document.getInitialProps(ctx);
const userAgent = ctx.req.headers['user-agent'];
return {
...props,
userAgent,
};
}
render() {
return (
<html>
<Head>
<title>ShareWalks</title>
<meta name="viewport" content="initial-scale=1.0, width=device-width" />
<link rel="stylesheet" href="https://sharewalks.com/shared.css" />
</Head>
<body>
<MuiThemeProvider muiTheme={getMuiTheme({ userAgent: this.props.userAgent })}>
<div>
<Main />
<NextScript />
</div>
</MuiThemeProvider>
</body>
</html>
);
}
}
pages/index.js (this works)
import React, {Component} from 'react';
import Head from 'next/head';
class App extends Component {
static async getInitialProps(args) {
return {};
}
render() {
return (
<div>
<Head>
<title>ShareWalks</title>
</Head>
<p>Yup</p>
</div>
);
}
}
export default App;
pages/walk.js (it errors here)
import React, {Component} from 'react';
import {Head} from 'next/head';
class Walk extends Component {
static async getInitialProps({query}) {
console.log('query: ', query);
return {id: query.id}; //added to props
}
render() {
return (
<div>
<Head>
<title>Walking</title>
</Head>
<p>{`Walk #${this.props.id}`}</p>
</div>
);
}
}
export default Walk;
When I go to localhost:8080/walk/2 or localhost:8080/walk?id=2 I get the error. The console does print out the id as expected, but then this:
query: { id: '2' }
TypeError: Cannot read property 'toLowerCase' of undefined
at a.renderDOM (/home/terry/myProjects/PWA/sw-next/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:36:390)
at a.render (/home/terry/myProjects/PWA/sw-next/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:36:228)
at a.read (/home/terry/myProjects/PWA/sw-next/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:35:250)
at renderToString (/home/terry/myProjects/PWA/sw-next/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:44:6)
at renderPage (/home/terry/myProjects/PWA/sw-next/node_modules/next/dist/server/render.js:174:26)
at Function.getInitialProps (/home/terry/myProjects/PWA/sw-next/node_modules/next/dist/server/document.js:83:25)
at Function._callee$ (/home/terry/myProjects/PWA/sw-next/.next/dist/pages/_document.js:138:59)
at tryCatch (/home/terry/myProjects/PWA/sw-next/node_modules/regenerator-runtime/runtime.js:62:40)
at Generator.invoke [as _invoke] (/home/terry/myProjects/PWA/sw-next/node_modules/regenerator-runtime/runtime.js:296:22)
at Generator.prototype.(anonymous function) [as next] (/home/terry/myProjects/PWA/sw-next/node_modules/regenerator-runtime/runtime.js:114:21)