-
Notifications
You must be signed in to change notification settings - Fork 26.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'canary' into clean-up-next-server
- Loading branch information
Showing
65 changed files
with
2,108 additions
and
356 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,105 +1,77 @@ | ||
--- | ||
description: Compile and deploy your Next.js app to production with ZEIT Now and other hosting alternatives. | ||
description: Deploy your Next.js app to production with ZEIT Now and other hosting options. | ||
--- | ||
|
||
# Deployment | ||
|
||
To go to production Next.js has a `next build` command. When run, it will compile your project and automatically apply numerous optimizations. | ||
## ZEIT Now (Recommended) | ||
|
||
## Prepare your package.json | ||
The easiest way to deploy Next.js to production is to use the **[ZEIT Now platform](https://zeit.co)** from the creators of Next.js. [ZEIT Now](https://zeit.co) is an all-in-one platform with Global CDN supporting static & JAMstack deployment and Serverless Functions. | ||
|
||
Ensure your `package.json` has the `"build"` and `"start"` scripts: | ||
|
||
```json | ||
{ | ||
"scripts": { | ||
"dev": "next", | ||
"build": "next build", | ||
"start": "next start" | ||
} | ||
} | ||
``` | ||
|
||
In the case that you'd want to do a [full static export](/docs/advanced-features/static-html-export.md) of the Next.js application add `next export` to the `"build"` script: | ||
|
||
```json | ||
{ | ||
"scripts": { | ||
"dev": "next", | ||
"build": "next build && next export", | ||
"start": "next start" | ||
} | ||
} | ||
``` | ||
### Getting started | ||
|
||
## ZEIT Now | ||
If you haven’t already done so, push your Next.js app to a Git provider of your choice: [GitHub](http://github.com/), [GitLab](https://gitlab.com/), or [BitBucket](https://bitbucket.org/). Your repository can be private or public. | ||
|
||
The easiest way to deploy Next.js to production is using the [ZEIT Now platform](https://zeit.co) from the creators of Next.js. | ||
Then, follow these steps: | ||
|
||
### Preview deployments | ||
1. [Sign up to ZEIT Now](https://zeit.co/signup) (no credit card is required). | ||
2. After signing up, you’ll arrive on the [“Create a new project”](https://zeit.co/new) page. Under “From your existing code”, choose the Git provider you use and set up an integration. (Instructions: [GitHub](https://zeit.co/docs/v2/git-integrations/zeit-now-for-github) / [GitLab](https://zeit.co/docs/v2/git-integrations/zeit-now-for-gitlab) / [BitBucket](https://zeit.co/docs/v2/git-integrations/zeit-now-for-bitbucket)). | ||
3. Once that’s set up, click “New Project From …” and import your Next.js app. It auto-detects that your app is using Next.js and sets up the build configuration for you. No need to change anything — everything just works! | ||
4. After importing, it’ll deploy your Next.js app and provide you with a deployment URL. Click “Visit” to see your app in production. | ||
|
||
ZEIT Now integrates directly with GitHub, GitLab, and Bitbucket to give you a unique shareable url for every commit and every pull request. This url can be shared with customers and can be used to run integration tests against. | ||
Congratulations! You’ve just deployed your Next.js app! If you have questions, take a look at the [ZEIT Now documentation](https://zeit.co/docs). | ||
|
||
### Hybrid Next.js | ||
> If you’re using a [custom server](/docs/advanced-features/custom-server.md) (which we don’t recommend), consider [other hosting options](#other-hosting-options). | ||
The [hybrid pages](/docs/basic-features/pages.md) approach is fully supported out of the box. Meaning that every page can either use [Static Generation](/docs/basic-features/pages.md#static-generation) or [Server-Side Rendering](/docs/basic-features/pages.md#server-side-rendering). | ||
### DPS: Develop, Preview, Ship | ||
|
||
In case of [Static Generation](/docs/basic-features/pages.md#static-generation) the page will automatically be served from the ZEIT Now Smart CDN. | ||
Let’s talk about the workflow we recommend using. [ZEIT Now](https://zeit.co) supports what we call the **DPS** workflow: **D**evelop, **P**review, and **S**hip: | ||
|
||
When the page is using [Server-Side Rendering](/docs/basic-features/pages.md#server-side-rendering) it will become an isolated serverless function automatically. This allows the page rendering to scale automatically and be independent—errors on one page won't affect another. | ||
- **Develop:** Write code in Next.js. Keep the development server running and take advantage of its hot code reloading feature. | ||
- **Preview:** Every time you push changes to a branch on GitHub / GitLab / BitBucket, ZEIT Now automatically creates a new deployment with a unique URL. You can view them on GitHub when you open a pull request, or under “Preview Deployments” on your project page on ZEIT Now. [Learn more about it here](https://zeit.co/features/deployment-previews). | ||
- **Ship:** When you’re ready to ship, merge the pull request to your default branch (e.g. `master`). ZEIT Now will automatically create a production deployment. | ||
|
||
API routes will also become separate serverless functions that execute and scale separately from each other. | ||
By using the DPS workflow, in addition to doing _code reviews_, you can do _deployment previews_. Each deployment creates a unique URL that can be shared or used for integration tests. | ||
|
||
### CDN + HTTPS by default | ||
### Optimized for Next.js | ||
|
||
Assets (JavaScript, CSS, images, fonts etc) and Statically Generated pages are automatically served through the ZEIT Now Smart CDN, ensuring these are always served close to your users. | ||
[ZEIT Now](https://zeit.co) is made by the creators of Next.js and has first-class support for Next.js. | ||
|
||
HTTPS is enabled by default and doesn't require extra configuration. | ||
For example, the [hybrid pages](/docs/basic-features/pages.md) approach is fully supported out of the box. | ||
|
||
### Getting started | ||
- Every page can either use [Static Generation](/docs/basic-features/pages.md#static-generation) or [Server-Side Rendering](/docs/basic-features/pages.md#server-side-rendering). | ||
- Pages that use [Static Generation](/docs/basic-features/pages.md#static-generation) and assets (JS, CSS, images, fonts, etc) will automatically be served from the [ZEIT Now Smart CDN](https://zeit.co/smart-cdn), which is blazingly fast. | ||
- Pages that use [Server-Side Rendering](/docs/basic-features/pages.md#server-side-rendering) and [API routes](/docs/api-routes/introduction.md) will automatically become isolated Serverless Functions. This allows page rendering and API requests to scale infinitely. | ||
|
||
#### From a git repository | ||
### Custom Domains, Environment Variables, Automatic HTTPS, and more | ||
|
||
You can link your project in [GitHub](https://zeit.co/new), [GitLab](https://zeit.co/new), or [Bitbucket](https://zeit.co/new) through the [web interface](https://zeit.co/new). This will automatically set up deployment previews for pull requests and commits. To learn more about ZEIT Now’s Git integration, take a look at [our documentation here](https://zeit.co/docs/v2/git-integration/). | ||
- **Custom Domains:** Once deployed on [ZEIT Now](https://zeit.co), you can assign a custom domain to your Next.js app. Take a look at [our documentation here](https://zeit.co/docs/v2/custom-domains). | ||
- **Environment Variables:** You can also set environment variables on ZEIT Now. Take a look at [our documentation here](https://zeit.co/docs/v2/build-step#using-environment-variables-and-secrets). You can then [use those environment variables](/docs/api-reference/next.config.js/environment-variables.md) in your Next.js app. | ||
- **Automatic HTTPS:** HTTPS is enabled by default (including custom domains) and doesn't require extra configuration. We auto-renew SSL certificates. | ||
- **More:** [Read our documentation](https://zeit.co/docs) to learn more about the ZEIT Now platform. | ||
|
||
#### Through the ZEIT Now CLI | ||
## Other hosting options | ||
|
||
You can install [Now CLI](https://zeit.co/download) from either npm or Yarn. Using npm, run the following command from your terminal: | ||
### Node.js Server | ||
|
||
```bash | ||
npm install -g now | ||
``` | ||
Next.js can be deployed to any hosting provider that supports Node.js. This is the approach you should take if you’re using a [custom server](/docs/advanced-features/custom-server.md). | ||
|
||
You can deploy your application by running the following command in the root of the project directory: | ||
Make sure your `package.json` has the `"build"` and `"start"` scripts: | ||
|
||
```bash | ||
now | ||
```json | ||
{ | ||
"scripts": { | ||
"dev": "next", | ||
"build": "next build", | ||
"start": "next start" | ||
} | ||
} | ||
``` | ||
|
||
You will receive a unique link similar to the following: https://your-project.username.now.sh. | ||
|
||
#### Custom domains | ||
|
||
Once deployed on ZEIT Now, your projects can be assigned to a custom domain of your choice. To learn more, take a look at [our documentation here](https://zeit.co/docs/v2/custom-domains/). | ||
|
||
## Self hosting | ||
|
||
Next.js can be deployed to any hosting provider that supports Node.js. In order to self-host there are two commands: `next build` and `next start`. | ||
|
||
`next build` builds the production application in the `.next` folder. | ||
|
||
`next start` starts a Node.js server that supports [hybrid pages](/docs/basic-features/pages.md), serving both statically generated and server-side rendered pages. | ||
|
||
Generally you'll have to follow these steps to deploy to production: | ||
`next build` builds the production application in the `.next` folder. After building, `next start` starts a Node.js server that supports [hybrid pages](/docs/basic-features/pages.md), serving both statically generated and server-side rendered pages. | ||
|
||
- Run `npm install` | ||
- Run `npm run build` (runs `next build`) | ||
- Potentially copy the `.next`, `node_modules`, and `package.json` to your server. | ||
- Run `npm run start` (runs `next start`) on the server | ||
### Static HTML Export | ||
|
||
In case you're doing a full static export using `next export` the steps are slightly different and don't involve using `next start`: | ||
If you’d like to do a static HTML export of your Next.js app, follow the directions on [our documentation](/docs/advanced-features/static-html-export.md). By default, `next export` will generate an `out` directory, which can be served by any static hosting service or CDN. | ||
|
||
- Run `npm install` | ||
- Run `npm run build` (runs `next build && next export`) | ||
- A `out` directory is generated by `next export` | ||
- Copy the `out` directory to the server and make sure it's served by your server | ||
> We strongly recommend using [ZEIT Now](https://zeit.co/) even if your Next.js app is fully static. [ZEIT Now](https://zeit.co/) is optimized to make static Next.js apps blazingly fast. `next export` works with Zero Config deployments on ZEIT Now. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
module.exports = { | ||
/* this needs to be set to false until a bug in the compression npm module gets fixed. | ||
reference: https://github.com/expressjs/compression/issues/122 | ||
*/ | ||
compress: false, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# Stripe keys | ||
STRIPE_PUBLISHABLE_KEY=pk_12345 | ||
STRIPE_SECRET_KEY=sk_12345 | ||
STRIPE_WEBHOOK_SECRET=whsec_1234 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
.env | ||
.DS_Store | ||
.vscode | ||
|
||
# Node files | ||
node_modules/ | ||
|
||
# Typescript | ||
dist | ||
|
||
# Next.js | ||
.next | ||
.now |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
# Example using Stripe with TypeScript and react-stripe-js 🔒💸 | ||
|
||
- Demo: https://nextjs-typescript-react-stripe-js.now.sh/ | ||
- CodeSandbox: https://codesandbox.io/s/nextjs-typescript-react-stripe-js-rqrss | ||
- Tutorial: https://dev.to/thorwebdev/type-safe-payments-with-next-js-typescript-and-stripe-4jo7 | ||
|
||
This is a full-stack TypeScript example using: | ||
|
||
- Frontend: | ||
- Next.js and [SWR](https://github.com/zeit/swr) | ||
- [react-stripe-js](https://github.com/stripe/react-stripe-js) for [Checkout](https://stripe.com/checkout) and [Elements](https://stripe.com/elements) | ||
- Backend | ||
- Next.js [API routes](https://nextjs.org/docs/api-routes/introduction) | ||
- [stripe-node with TypeScript](https://github.com/stripe/stripe-node#usage-with-typescript) | ||
|
||
### Included functionality | ||
|
||
- Making `.env` variables available to next: [next.config.js](next.config.js) | ||
- **_NOTE_**: when deploying with Now you need to [add your secrets](https://zeit.co/docs/v2/serverless-functions/env-and-secrets) and specify a [now.json](/now.json) file. | ||
- Implementation of a Layout component that loads and sets up Stripe.js and Elements for usage with SSR via `loadStripe` helper: [components/Layout.tsx](components/Layout.tsx). | ||
- Stripe Checkout | ||
- Custom Amount Donation with redirect to Stripe Checkout: | ||
- Frontend: [pages/donate-with-checkout.tsx](pages/donate-with-checkout.tsx) | ||
- Backend: [pages/api/checkout_sessions/](pages/api/checkout_sessions/) | ||
- Checkout payment result page that uses [SWR](https://github.com/zeit/swr) hooks to fetch the CheckoutSession status from the API route: [pages/result.tsx](pages/result.tsx). | ||
- Stripe Elements | ||
- Custom Amount Donation with Stripe Elements & PaymentIntents (no redirect): | ||
- Frontend: [pages/donate-with-elements.tsx](pages/donate-with-checkout.tsx) | ||
- Backend: [pages/api/payment_intents/](pages/api/payment_intents/) | ||
- Webhook handling for [post-payment events](https://stripe.com/docs/payments/accept-a-payment#web-fulfillment) | ||
- By default Next.js API routes are same-origin only. To allow Stripe webhook event requests to reach our API route, we need to add `micro-cors` and [verify the webhook signature](https://stripe.com/docs/webhooks/signatures) of the event. All of this happens in [pages/api/webhooks/index.ts](pages/api/webhooks/index.ts). | ||
- Helpers | ||
- [utils/api-helpers.ts](utils/api-helpers.ts) | ||
- helpers for GET and POST requests. | ||
- [utils/stripe-helpers.ts](utils/stripe-helpers.ts) | ||
- Format amount strings properly using `Intl.NumberFormat`. | ||
- Format amount for usage with Stripe, including zero decimal currency detection. | ||
|
||
## How to use | ||
|
||
### Using `create-next-app` | ||
|
||
Execute [`create-next-app`](https://github.com/zeit/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example: | ||
|
||
```bash | ||
npm init next-app --example with-stripe-typescript with-stripe-typescript-app | ||
# or | ||
yarn create next-app --example with-stripe-typescript with-stripe-typescript-app | ||
``` | ||
|
||
### Download manually | ||
|
||
Download the example: | ||
|
||
```bash | ||
curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/with-stripe-typescript | ||
cd with-stripe-typescript | ||
``` | ||
|
||
### Required configuration | ||
|
||
Copy the `.env.example` file into a file named `.env` in the root directory of this project: | ||
|
||
```bash | ||
cp .env.example .env | ||
``` | ||
|
||
You will need a Stripe account ([register](https://dashboard.stripe.com/register)) to run this sample. Go to the Stripe [developer dashboard](https://stripe.com/docs/development#api-keys) to find your API keys and replace them in the `.env` file. | ||
|
||
```bash | ||
STRIPE_PUBLISHABLE_KEY=<replace-with-your-publishable-key> | ||
STRIPE_SECRET_KEY=<replace-with-your-secret-key> | ||
``` | ||
|
||
Now install the dependencies and start the development server. | ||
|
||
```bash | ||
npm install | ||
npm run dev | ||
# or | ||
yarn | ||
yarn dev | ||
``` | ||
|
||
### Forward webhooks to your local dev server | ||
|
||
First [install the CLI](https://stripe.com/docs/stripe-cli) and [link your Stripe account](https://stripe.com/docs/stripe-cli#link-account). | ||
|
||
Next, start the webhook forwarding: | ||
|
||
```bash | ||
stripe listen --forward-to localhost:3000/api/webhooks | ||
``` | ||
|
||
The CLI will print a webhook secret key to the console. Set `STRIPE_WEBHOOK_SECRET` to this value in your `.env` file. | ||
|
||
### Deploy it to the cloud with ZEIT Now | ||
|
||
Install [Now](https://zeit.co/now) ([download](https://zeit.co/download)) | ||
|
||
Add your Stripe [secrets to Now](https://zeit.co/docs/v2/serverless-functions/env-and-secrets): | ||
|
||
```bash | ||
now secrets add stripe_publishable_key pk_*** | ||
now secrets add stripe_secret_key sk_*** | ||
now secrets add stripe_webhook_secret whsec_*** | ||
``` | ||
|
||
To start the deploy, run: | ||
|
||
```bash | ||
now | ||
``` | ||
|
||
After the successful deploy, Now will show you the URL for your site. Copy that URL (`https://your-url.now.sh/api/webhooks`) and create a live webhook endpoint [in your Stripe dashboard](https://stripe.com/docs/webhooks/setup#configure-webhook-settings). | ||
|
||
**_Note_** that your live webhook will have a different secret. To update it in your deployed application you will need to first remove the existing secret and then add the new secret: | ||
|
||
```bash | ||
now secrets rm stripe_webhook_secret | ||
now secrets add stripe_webhook_secret whsec_*** | ||
``` | ||
|
||
As the secrets are set as env vars in the project at deploy time, we will need to redeploy our app after we made changes to the secrets. Run `now` again to redeploy with the new secret value. |
64 changes: 64 additions & 0 deletions
64
examples/with-stripe-typescript/components/CheckoutForm.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import React, { useState } from 'react' | ||
|
||
import CustomDonationInput from '../components/CustomDonationInput' | ||
|
||
import { fetchPostJSON } from '../utils/api-helpers' | ||
import { formatAmountForDisplay } from '../utils/stripe-helpers' | ||
import * as config from '../config' | ||
|
||
import { useStripe } from '@stripe/react-stripe-js' | ||
|
||
const CheckoutForm: React.FunctionComponent = () => { | ||
const [input, setInput] = useState({ customDonation: config.MIN_AMOUNT }) | ||
const stripe = useStripe() | ||
|
||
const handleInputChange: React.ChangeEventHandler<HTMLInputElement> = e => | ||
setInput({ | ||
...input, | ||
[e.currentTarget.name]: e.currentTarget.value, | ||
}) | ||
|
||
const handleSubmit: React.FormEventHandler<HTMLFormElement> = async e => { | ||
e.preventDefault() | ||
// Create a Checkout Session. | ||
const response = await fetchPostJSON('/api/checkout_sessions', { | ||
amount: input.customDonation, | ||
}) | ||
|
||
if (response.statusCode === 500) { | ||
console.error(response.message) | ||
return | ||
} | ||
|
||
// Redirect to Checkout. | ||
const { error } = await stripe!.redirectToCheckout({ | ||
// Make the id field from the Checkout Session creation API response | ||
// available to this file, so you can provide it as parameter here | ||
// instead of the {{CHECKOUT_SESSION_ID}} placeholder. | ||
sessionId: response.id, | ||
}) | ||
// If `redirectToCheckout` fails due to a browser or network | ||
// error, display the localized error message to your customer | ||
// using `error.message`. | ||
console.warn(error.message) | ||
} | ||
|
||
return ( | ||
<form onSubmit={handleSubmit}> | ||
<CustomDonationInput | ||
name={'customDonation'} | ||
value={input.customDonation} | ||
min={config.MIN_AMOUNT} | ||
max={config.MAX_AMOUNT} | ||
step={config.AMOUNT_STEP} | ||
currency={config.CURRENCY} | ||
onChange={handleInputChange} | ||
/> | ||
<button type="submit" disabled={!stripe}> | ||
Donate {formatAmountForDisplay(input.customDonation, config.CURRENCY)} | ||
</button> | ||
</form> | ||
) | ||
} | ||
|
||
export default CheckoutForm |
Oops, something went wrong.