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

Improve rewrites documentation #34725

Merged
merged 7 commits into from Feb 24, 2022
27 changes: 26 additions & 1 deletion docs/api-reference/next.config.js/rewrites.md
Expand Up @@ -300,15 +300,20 @@ module.exports = {
<summary><b>Examples</b></summary>
<ul>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/custom-routes-proxying">Incremental adoption of Next.js</a></li>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/with-zones">Using Multiple Zones</a></li>
</ul>
</details>

Rewrites allow you to rewrite to an external url. This is especially useful for incrementally adopting Next.js.
Rewrites allow you to rewrite to an external url. This is especially useful for incrementally adopting Next.js. The following is an example rewrite for redirecting the `/blog` route of your main app to an external site.

```js
module.exports = {
async rewrites() {
return [
{
source: '/blog',
destination: 'https://example.com/blog',
},
{
source: '/blog/:slug',
destination: 'https://example.com/blog/:slug', // Matched parameters can be used in the destination
Expand All @@ -318,6 +323,26 @@ module.exports = {
}
```

If you're using `trailingSlash: true`, you also need to insert a trailing slash in the rewrites and use a special wildcard.

```js
module.exports = {
trailingSlash: 'true',
async rewrites() {
return [
{
source: '/blog/',
destination: 'https://example.com/blog/',
},
{
source: '/blog/:path(.+)',
Copy link
Member

Choose a reason for hiding this comment

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

This seems like a bug, wdyt @ijjk 🤔

Suggested change
source: '/blog/:path(.+)',
source: '/blog/:path(.+)',

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For context, I discovered that :path* doesn't catch trailing slashes so Davis came up with a wildcard expression that does.

Copy link
Member

Choose a reason for hiding this comment

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

We should be handling the trailing slash here

// we add an optional trailing slash at the end for easier
// configuring between trailingSlash: true/false
can you provide a reproduction where this isn't working?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@ijjk yep! Here's a reproduction. Click on the "not working" demo link below, navigate to a specific blog post, then reload the page. It will redirect infinitely.

If you want to take a look at the code, here are the full repos. They both have trailingSlash: true:

Copy link
Member

Choose a reason for hiding this comment

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

Oh it looks like the destination for this rewrite needs to end with a trailingSlash to match the other deployments expectation e.g. does changing it to the below resolve this?

destination: `${BLOG_URL}/blog/:path*/`

Copy link
Member

Choose a reason for hiding this comment

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

I think documenting that the destination for a rewrite needs to honor the external destination's trailingSlash config makes sense

Copy link
Contributor Author

@Nutlope Nutlope Feb 24, 2022

Choose a reason for hiding this comment

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

Good catch, it works when you include a trailing slash for both the source and destination like this.

{
  source: "/blog/:path*/",
  destination: `${BLOG_URL}/blog/:path*/`,
},

I'm assuming this is better than the :path(.+) wildcard so I just updated the PR to reflect that.

destination: 'https://example.com/blog/:path(.+)',
},
]
},
}
```

### Incremental adoption of Next.js

You can also have Next.js fall back to proxying to an existing website after checking all Next.js routes.
Expand Down