owned this note
owned this note
Published
Linked with GitHub
# Painlessly Build and Deploy Next.js Apps With Nx
[Next.js](https://nextjs.org/) is a super cool meta-framework that is built on top of React. One of the major benefits of the framework is how much you get out of the box, with zero configuration.
For example, to create a new app and serve a new app you can simply run:
```
mkdir demo && cd demo
yarn init -y
yarn add next react react-dom
mkdir pages
yarn next dev
```
Running the `dev` command will result in a dev server starting at http://localhost:3000. Since we don’t have any pages, navigating to it results in a 404 page.
![](https://i.imgur.com/IhGOG7g.png)
You can remedy this by creating a `pages/index.tsx` file that exports a React component to render the index page. I won’t go over this in detail since it’s already covered in the their [Getting Started](https://nextjs.org/learn/basics/getting-started) guide.
## Some Configurations Required
There are additional steps involved when setting up Next if you want to use different plugins. Say you want to use SCSS for styling components, then you’ll need to install and configure the `@zeit/next-sass` plugin.
```
yarn add --dev @zeit/next-sass
```
Then update the `next.config.js` file as follows.
```
const withSass = require('@zeit/next-sass');
module.exports = withSass({
cssModules: true // assuming you want css modules :)
});
```
Or alternatively, if you want to use `styled-components` instead, then you don’t need a Next plugin; but you need to add the necessary dependencies, update your babel config, and then create a custom `pages/_document.tsx` component to support SSR.
The setup for styled-components is available in the Next [repo](https://github.com/zeit/next.js/tree/master/examples/with-styled-components), and it’s not hard but requires a few manual steps. So let's see how we can create and build the same app using Nx.
## Next + Nx
Now, contrast the previous steps with Nx.
```
npx create-nx-workspace my-workspace --appName=demo --preset=next --style=scss
```
**Note:** You can use `--style=styled-components` if you prefer that instead.
The command above will create a new Nx workspace. We can run the demo app in development mode as follows.
```
cd my-workspace
nx serve demo
```
**Note:** You will need to install `nx` globally (`npm install -g @nrwl/cli`), or use `npx nx` instead.
And that's it! No additional installation or configuration. If you use `--style=styled-components`, then Nx will create a custom document for you that works with `styled-components`, install the necessary dependencies, and set up babel config correctly. Othewise, the `scss` version will install the `@zeit/next-sass` plugin, and update the `next.config.js` to use it.
Navigating to `http://localhost:4200` will show the generated app.
![](https://i.imgur.com/dcNlbkR.png)
You can also create new pages by running the `generate` command.
```
# Or just `nx g` for short
nx generate page About --project=demo --style=scss
```
This tells Nx to add a new `apps/demo/pages/about.tsx` component to the `demo` project that we generated earlier.
The same thing goes for new components.
```
nx g component PartyPopper --project=demo --style=scss
```
This will generate the component under the `apps/demo/components/party-popper/` folder.
Let’s update our `PartyPopper` component and use it in the `About` page. Update your code as follows.
**apps/demo/components/party-popper/party-popper.tsx**:
```
import React from 'react';
export const PartyPopper = () => <span>🎉</span>;
export default PartyPopper;
```
**apps/demo/pages/about.tsx**:
```
import React from 'react';
import PartPopper from '../components/party-popper/party-popper';
const About = () => {
return (
<div>
<h1>
You found the about page! <PartPopper />
</h1>
</div>
);
};
export default About;
```
And now when you navigate to http://localhost:4200/about you should see the new page.
![](https://i.imgur.com/S7Hw867.png)
You can also run the *generated E2E tests* that correspond with the demo app. By default, all apps generated through Nx comes with [Cypress](https://www.cypress.io/) tests. You can run them with `nx e2e demo-e2e`, and the specs are in the `apps/demo-e2e` folder.
To recap, so far we've seen how we can generate a new Nx workspace with a Next app. We also saw how easy it is to generate new pages and components using the `generate` command.
**Pro-tip:** The `generate` command runs [_schematics_](https://nx.dev/react/cli/generate) in Nx, while targets such as `serve` uses [_builders_](https://nx.dev/react/cli/run) to perform a task. To see a full list of available schematics and builders, run `nx list @nrwl/next`.
## Building and Deploying with Nx
There are many ways to deploy your Next app. You can either export a static website or build a Node application with pre-rendering support. An exported static website is pretty simple to deploy, since it just involves pushing the `public` folder to any host that can serve HTML pages — or CDN.
In this example, we will look at how to build and deploy the pre-rendered Node application to [Heroku](https://heroku.com/).
First, will need to [Heroku CLI](https://devcenter.heroku.com/categories/command-line), so go ahead and install that if you haven’t already.
Secondly, you’ll need to login to your account, and create a new app.
```
heroku login
heroku apps:create my-workspace-demo
```
**Note:** I'm using the name `my-workspace-demo` here, but it may not be available for you so choose one that is available. Just make sure you replace all subsequent usages of `my-workspace-demo` with your actual application name.
Next, let’s also create a `Dockerfile` for the project so we can use Heroku's container support.
**apps/demo/Dockerfile**:
```
FROM node:12-alpine
WORKDIR /app
COPY .next ./.next
COPY package.json ./package.json
RUN yarn
CMD yarn next start -p $PORT
```
Then we can update our `workspace.json` file — which maintains a list of projects, and their targets (e.g. `build`, `test`, etc.) available to each project. We want to look for the `projects.demo.architect` entry, and add the `deploy` target.
**workspace.json**:
```
{
"version": 1,
"projects": {
"demo": {
// ...
"architect": {
"deploy": { // <-- NEW
"builder": "@nrwl/workspace:run-commands",
"options": {
"cwd": "dist/apps/demo",
"parallel": false,
"commands": [
{
"command": "cp ../../..apps/demo/Dockerfile ."
},
{
"command": "heroku container:push web -a my-workspace-demo"
},
{
"command": "heroku container:release web -a my-workspace-demo"
}
]
}
},
// ...
}
}
}
}
```
And finally, we can run the production build and deploy.
```
nx build demo
nx deploy demo
```
Once Heroku is finished doing its thing, you should see a link to the deployed app.
## Summary
Next is a great framework for building modern websites and applications. By using Nx with Next, you gain access even more powerful tools and abstractions that can greatly improve your development workflow.
The Nx features presented here are only the tip of the iceberg. There are a lot more awesome features to discover — such as the [distributed cache](https://blog.nrwl.io/how-to-never-build-or-test-the-same-code-twice-2dc58e413279) to greatly increase productivity. To learn more about Nx, please check out [nx.dev](https://nx.dev/react).
## Addendum: Working in a Monorepo
You may be wondering why our `demo` app lives in the `apps` folder rather being at the root of the repo like a normal Next project. As you may have guessed, Nx sets the workspace up as a monorepo.
There are many benefits of using a monorepo; including code sharing, tooling consistency, and being able to commit changes to multiple related projects at once. The [*Getting Started guide*](https://nx.dev/react/getting-started/why-nx) provides more information on this, and how Nx can help you manage your monorepo.
Imagine that you have two Next apps with a common UI library, and an express backend. Your workspace stucture may look something like this:
```
apps/
backend/
intranet-portal/
marketing-website/
libs/
ui/
```
To generate the above with Nx, you'd run this series of commands:
```
# Create new workspace
npx create-nx-workspace@latest happyorg \
--preset=next --appName=intranet-portal --style=css
cd happyorg
# Dependencies for backend app
yarn add express
yarn add --dev @nrwl/node @nrwl/next
nx g @nrwl/next:app marketing-website --style=css
nx g @nrwl/react:lib ui --style=css
nx g @nrwl/node:app backend
```
The `generate` commands above now have a package prefixed before the schematic name. In our previous examples we relied on the workspace's default schematic (i.e. `@nrwl/next` so we could leave the package out). These packages are Nx plugins, and there are officially maintained ones, as well as some blessed community plugins. For more information on plugins you can run `nx list`, and read the [plugins docs](https://nx.dev/react/plugins/overview).
Another useful feature of Nx is the ability to visualize your project dependency graph by running the `nx dep-graph` command.
![](https://i.imgur.com/qbkJeVW.png)