Tony Spiro
December 06, 2016
Next.js is an amazing new addition to the React open-source ecosystem. It is “a minimalistic framework for universal server-rendered React applications” that makes the process of building these types of applications much faster and easier. Recently I demoed a new app on the Cosmic Apps page that is built using the Next.js framework. I’ve built a few React Universal apps from scratch before and I found taking the Next.js route to speed things along quite a bit. And adding content management capability from Cosmic to the Next.js structure was very intuitive.
In this tutorial I’m going to show you how I built the Next.js application and integrated content powered by Cosmic. This full app is available on the Cosmic Apps page for you to download, hack, install and deploy live.
Getting Started
Let’s get started by creating our app and installing next:
mkdir next.js-website
cd next.js-website
yarn add next
Creating Pages
Now lets create a new folder to hold our pages.
mkdir pages
With Next.js, any page that we add to our pages folder will be available at its corresponding url. So index.js will be available at / and about.js will be found at /about and so on. Let’s first create our index.js file. Add the following to index.js:
import React from 'react' export default class Home extends React.Component { render () { return <div>Hello World</div> } }
Now let’s start our next server to see our page:
next
Navigate to http://localhost:3000 to see our Hello World example. Next let’s add another page to show our about page content. In a file titled about.js add:
import React from 'react' export default class Home extends React.Component { render () { return <div>About me</div> } }
Then run next again. Now go to http://localhost:3000/about to see this page.
We could hard code the content for all of our pages, but for our purposes, let’s hook up the Cosmic API so we can let our team add and edit content using the Cosmic CMS API. For each page we want to be able to pull that specific page from the Cosmic API and serve the content to our Next.js application.
Adding Cosmic-Powered Content
First install the Cosmic NPM module:
yarn add cosmicjs
Then create a new folder titled models and add the following to a file titled cosmic.js:
const config = {
bucket: {
slug: 'nextjs-website' // add your bucket slug here
}
}
import Cosmic from 'cosmicjs'
export default {
getPage(slug) {
const data = new Promise(resolve => {
Cosmic.getObject(config, { slug }, (err, res) => {
resolve(res)
})
})
return data
}
}
So the purpose of this piece of code is to take whatever slug is supplied to the "getPage" function and render the Cosmic Object.
Dynamic Pages
Let’s create a basic page structure for all of our pages. Create a folder titled "templates" and addd the following file titled basic-page.js:
import React from 'react' export default class BasicPage extends React.Component { render() { const page = this.props.page return ( <div> <main> <h1>{page.title}</h1> <div dangerouslySetInnerHTML={{__html: page.content}}/> </main> </div> ) } }
Next let’s edit our index.js file to include the following:
import React from 'react' import BasicPage from '../templates/basic-page' import Cosmic from '../models/cosmic' export default class Home extends React.Component { static async getInitialProps () { return await Cosmic.getPage('home') } render () { const page = this.props.object return <BasicPage page={page}/> } }
Now we have created a basic page template that will render the page title and content. And in our index.js file, before rendering, the getInitialProps function will fetch the page content from the Cosmic API. Now for our about page, all we need to do is change the slug. about.js now looks like this:
import React from 'react'
import BasicPage from '../templates/basic-page'
import Cosmic from '../models/cosmic'
export default class Home extends React.Component {
static async getInitialProps () {
return await Cosmic.getPage('about')
}
render () {
const page = this.props.object
return <BasicPage page={page}/>
}
}
Now run the application:
next
Navigate to / and /about and notice that the Cosmic content comes through not only when you view source (server side) but it also renders on the client as a React Universal Application.
In Conclusion
So when creating a React universal application using the Next.js framework there was a lot of stuff I didn’t have to do: I didn’t have to set up react-router. I didn’t have to set up Flux or Redux to manage state. I didn’t have to do any server-side node.js coding. I didn't have to do a lot (or any!) webpack configuration for hot-reloading and bundle routing. So yea, I saved a TON of time on boilerplate setup and config using the Next.js framework to accomplish my universal React needs. It really is a remarkable piece of tech and I’m looking forward to see where it will go next (no pun intended).
I hope you enjoyed this tutorial. If you have any questions about setting up your Cosmic-powered Next.js Universal App reach our to us in our Slack community or on Twitter.