Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add example for proxying upstream with custom routes #14374

Merged
merged 9 commits into from
Jun 22, 2020
52 changes: 52 additions & 0 deletions examples/custom-routes-proxying/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Custom Routes Proxying Example

This example shows the most basic example using Next.js' new custom routes feature to proxy requests to an upstream server. We have 3 pages: `pages/index.js`, `pages/about.js`, and `pages/hello/[slug].js`. All of these pages will be matched against Next.js and any other path will be proxied to the upstream server.

This approach is very helpful when you are trying to incrementally migrate your application to Next.js but still need to fallback to an existing application. You can add pages to your Next.js application one-by-one and then for non-migrated pages Next.js can proxy to the existing application until they are able to be migrated.

## How to use

### Using `create-next-app`

Execute [`create-next-app`](https://github.com/vercel/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
npx create-next-app --example custom-routes-proxying custom-routes-proxying-app
# or
yarn create next-app --example custom-routes-proxying custom-routes-proxying-app
```

### Download manually

Download the example:

```bash
curl https://codeload.github.com/vercel/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/custom-routes-proxying
cd custom-routes-proxying
```

Install it:

```bash
npm install
# or
yarn
```

Start upstream server in one terminal

```bash
npm run start-upstream
# or
yarn start-upstream
```

Start Next.js in another terminal

```bash
npm run dev
# or
yarn dev
```

Deploy it to the cloud with [Vercel](https://vercel.com/import?filter=next.js&utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)). Note: to deploy this example you will need to configure an existing upstream server.
18 changes: 18 additions & 0 deletions examples/custom-routes-proxying/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module.exports = {
experimental: {
async rewrites() {
return [
// we need to define a no-op rewrite to trigger checking
// all pages/static files before we attempt proxying
{
source: '/:path*',
destination: '/:path*',
},
{
source: '/:path*',
destination: `http://localhost:${process.env.UPSTREAM_PORT}/:path*`,
},
]
},
},
}
16 changes: 16 additions & 0 deletions examples/custom-routes-proxying/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "custom-routes-proxying",
"version": "1.0.0",
"scripts": {
"dev": "cross-env UPSTREAM_PORT=3001 next dev",
"build": "next build",
"start": "cross-env UPSTREAM_PORT=3001 next start",
"start-upstream": "cross-env UPSTREAM_PORT=3001 node server.js"
},
"dependencies": {
"cross-env": "7.0.2",
"next": "latest",
"react": "16.8.6",
"react-dom": "16.8.6"
}
}
11 changes: 11 additions & 0 deletions examples/custom-routes-proxying/pages/about.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Link from 'next/link'
export default function About() {
return (
<div>
<h3>This is the /about page. </h3>
<Link href="/">
<a> &larr; Back home</a>
</Link>
</div>
)
}
13 changes: 13 additions & 0 deletions examples/custom-routes-proxying/pages/hello/[slug].js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import Link from 'next/link'
import { useRouter } from 'next/router'

export default function About() {
return (
<div>
<h3>This is the `hello/[slug]` page. slug: {useRouter().query.slug}</h3>
<Link href="/">
<a> &larr; Back home</a>
</Link>
</div>
)
}
15 changes: 15 additions & 0 deletions examples/custom-routes-proxying/pages/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import Link from 'next/link'
export default function Home() {
return (
<div>
<h3>Hello World.</h3>
<Link href="/about">
<a>About</a>
</Link>
<br />
<Link href="/hello/[slug]" as="/hello/world">
<a>Hello world</a>
</Link>
</div>
)
}
11 changes: 11 additions & 0 deletions examples/custom-routes-proxying/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const http = require('http')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's remove this file, it should show proxying to an external website, potentially you can host a "legacy frontend" as an example

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to use an existing site as the upstream proxy instead 👍

const PORT = process.env.UPSTREAM_PORT

const server = http.createServer((req, res) => {
console.log(`Upstream server got request for ${req.url}`)
res.end(`hi from upstream server, requested: ${req.url}`)
})

server.listen(PORT, () => {
console.log(`Upstream server listening at ::${PORT}`)
})