Get started:
mkdir hello-next
cd hello-next
npm init -y
npm install --save react react-dom next
mkdir pages
Add to package.json:
{
"scripts": {
"dev": "next"
}
}
Start dev server:
npm run dev
Create an index file in pages directory:
const Index = () => (
<div>
<p>Hello Next.js</p>
</div>
)
export default Index
Add a link:
import Link from 'next/link'
const Index = () => (
<div>
<Link href="/about">
<a>About Page</a>
</Link>
<p>Hello Next.js</p>
</div>
)
export default Index
Styling a link:
<Link href="/about">
<a style={{ fontSize: 20 }}>About Page</a>
</Link>
Anything that takes an onClick prop will work:
<Link href="/about">
<button>Go to About Page</button>
</Link>
Example header component:
import Link from 'next/link'
const linkStyle = {
marginRight: 15
}
const Header = () => (
<div>
<Link href="/">
<a style={linkStyle}>Home</a>
</Link>
<Link href="/about">
<a style={linkStyle}>About</a>
</Link>
</div>
)
export default Header
Using the header component:
import Header from '../components/Header'
export default () => (
<div>
<Header />
<p>Hello Next.js</p>
</div>
)
Example layout component:
import Header from './Header'
const layoutStyle = {
margin: 20,
padding: 20,
border: '1px solid #DDD'
}
const Layout = (props) => (
<div style={layoutStyle}>
<Header />
{props.children}
</div>
)
export default Layout
Using the layout component:
// pages/index.js
import Layout from '../components/MyLayout.js'
export default () => (
<Layout>
<p>Hello Next.js</p>
</Layout>
)
Three other ways to create a layout component:
import withLayout from '../lib/layout'
const Page = () => (
<p>This is the about page</p>
)
export default withLayout(Page)
const Page = () => (
<p>This is the about page</p>
)
export default () => (<Layout page={Page}/>)
const content = (<p>This is the about page</p>)
export default () => (<Layout content={content}/>)
Adding a list of posts
import Layout from '../components/MyLayout.js'
import Link from 'next/link'
const PostLink = (props) => (
<li>
<Link href={`/post?title=${props.title}`}>
<a>{props.title}</a>
</Link>
</li>
)
export default () => (
<Layout>
<h1>My Blog</h1>
<ul>
<PostLink title="Hello Next.js"/>
<PostLink title="Learn Next.js is awesome"/>
<PostLink title="Deploy apps with Zeit"/>
</ul>
</Layout>
)
Passing data via query strings
const PostLink = (props) => (
<li>
<Link href={`/post?title=${props.title}`}>
<a>{props.title}</a>
</Link>
</li>
)
Create a 'post' page
import Layout from '../components/MyLayout.js'
export default (props) => (
<Layout>
<h1>{props.url.query.title}</h1>
<p>This is the blog post content.</p>
</Layout>
)
Modified way
import Layout from '../components/MyLayout.js'
const Content = (props) => (
<div>
<h1>{props.url.query.title}</h1>
<p>This is the blog post content.</p>
</div>
)
export default props => (
<Layout>
<Content />
</Layout>
)
Route masking
import Layout from '../components/MyLayout.js'
import Link from 'next/link'
const PostLink = (props) => (
<li>
<Link as={`/p/${props.id}`} href={`/post?title=${props.title}`}>
<a>{props.title}</a>
</Link>
</li>
)
export default () => (
<Layout>
<h1>My Blog</h1>
<ul>
<PostLink id="hello-nextjs" title="Hello Next.js"/>
<PostLink id="learn-nextjs" title="Learn Next.js is awesome"/>
<PostLink id="deploy-nextjs" title="Deploy apps with Zeit"/>
</ul>
</Layout>
)
Custom routes
// server.js
const express = require('express')
const next = require('next')
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()
app.prepare()
.then(() => {
const server = express()
server.get('/p/:id', (req, res) => {
const actualPage = '/post'
const queryParams = { title: req.params.id }
app.render(req, res, actualPage, queryParams)
})
server.get('*', (req, res) => {
return handle(req, res)
})
server.listen(3000, (err) => {
if (err) throw err
console.log('> Ready on http://localhost:3000')
})
})
.catch((ex) => {
console.error(ex.stack)
process.exit(1)
})