` wrapping the body, we return a wrapping `
`.
---
# Sidebar about `({ children })`
There's two things happening here:
1. An argument containing some special properties, in particular `children` which is a React element containing the children nodes
2. The argument is be destructured on the fly to create a new variable called `children`
---
```js
export default ({ children }) => (
{ children }
);
```
Equivalent to:
```js
export default (props) => (
{ props.children }
);
```
The `{` and closing `}` is a JSX expression, so the contents is returned to be interpreted by JSX.
---
# Common `head` elements
I've personally found hard in React, but they're part of the package for Next.
```js
// filename: components/Layout.js
import Head from 'next/head';
export default ({ children, title = 'My cool site' }) => (
{ title }
{ children }
);
```
---
# What about viewport, common styles, etc?
This could go in `` or we could make a custom document container.
1. Add ./pages/_document.js
2. Extend `next/document`
---
```js
import Document, { Head, Main, NextScript } from 'next/document';
export default class MyDocument extends Document {
render() {
*
}
}
```
---
# Error pages
There's a few ways to handle errors, we'll look at the basic way now.

---
To add a custom error page, we:
1. Add `/pages/_error.js`
2. And return custom content.
```js
// filename: pages/_error.js
export default () => Nope.
;
```
*Note: that I found you have to restart the `npm run dev` process to get this "system" file to be picked up.*
---
```js
import React from 'react';
export default class Error extends React.Component {
static getInitialProps({ res, err }) {
const statusCode = res ?
res.statusCode :
err ?
err.statusCode : null;
return { statusCode };
}
render() {
return { this.props.statusCode }
}
}
```
???
Sample from [Next.js _error.js](https://github.com/zeit/next.js#custom-error-handling)
---
# Let's add some content…
1. Add ./data/schedule.json
2. `import` into ./pages/index.js
3. Loop over and render each session
_Bonus_: remove the breaks from the schedule
???
For now we'll hard code the content, in the next section, we'll get it from an external source
---
```js
// filename: ./pages/index.js
import Session from '../components/Session';
import schedule from '../data/schedule.json';
// ...
// in the render:
{schedule.map((session, i) => )}
```
???
Remember that JSX the curly braces return the expression - so the array of `Session` elements.
---
# Using query strings
1. Create ./pages/session.js
2. .. filter the schedule down from the query: /session?slug=memory
Slug is:
```js
export default ({ url }) => {
const slug = url.query.slug;
// ...
}
```
???
Note that only the page component gets the `url` property by default, and if you want your components to receive them, you need to pass them along.
---
# Clean URLs
From /session?slug=memory to /session/memory
---
# Clean URLs in the client
```js
```

---
class: middle
# Server different story
.left[```bash
❯ curl -D /dev/stderr http://localhost:3000/session/memory | textutil -convert txt -stdin -stdout
*HTTP/1.1 404 Not Found
X-Powered-By: Next.js 4.1.3
Content-Type: text/html
Content-Length: 2119
Date: Sun, 29 Oct 2017 15:59:20 GMT
Connection: keep-alive
HomeAboutContact
Nope 😢
This page could not be found.
© Don't steal! Share ❤️
```]
---
# Adding server side support
1. Add ./lib/server.js with [git.io/vFtzI](https://git.io/vFtzI)
2. Add …
```js
server.get('/session/:slug', (req, res) => {
const { slug } = req.params;
app.render(req, res, '/session', { slug });
});
```
???
Note that we'll lose the query string if it's included
---
# Gotcha: query strings

---
But [/session/memory?rating=4](http://localhost:3000/session/memory?rating=4) doesn't work from the server, because the server request handler didn't pass the query through.
Fix:
```js
server.get('/session/:slug', (req, res) => {
const { slug } = req.params;
* app.render(req, res, '/session', { slug, ...req.query });
});
```
---
# Environment variables
Secret keys, dev settings and more.
```bash
# dev
SHOW_SPEAKERS=1 npm run dev
```
```bash
# production
SHOW_SPEAKERS=0 npm start
```
???
It's solved using a next.config.js file.