Skip to content

Commit 413fbd6

Browse files
Netailijjk
andauthored
fix: absolute assetPrefix url with path (#77256)
### What? When an absolute url with path has been set as the assetPrefix, the path is not used when serving the bundles. Instead the bundles are served directly on the root. The rewrite did not seem to take a path into account, only a host. e.g. when the assetPrefix is set to `https://example.vercel.sh/custom-asset-prefix`, it does not serve the bundles from `<host>/custom-asset-prefix/_next/*` instead only from `<host>/_next/*` Related; #77118 --------- Co-authored-by: JJ Kasper <[email protected]>
1 parent f5198b4 commit 413fbd6

File tree

6 files changed

+84
-13
lines changed

6 files changed

+84
-13
lines changed

packages/next/src/lib/load-custom-routes.test.ts

+14-1
Original file line numberDiff line numberDiff line change
@@ -144,12 +144,25 @@ describe('loadCustomRoutes', () => {
144144

145145
it('does not insert assetPrefix rewrite for /_next/ paths when assetPrefix is absolute URL', async () => {
146146
const customRoutes = await loadCustomRoutes({
147-
assetPrefix: 'https://example.com/custom-asset-prefix',
147+
assetPrefix: 'https://example.com',
148148
})
149149
expect(customRoutes.rewrites.beforeFiles).toEqual([])
150150
expect(customRoutes.rewrites.afterFiles).toEqual([])
151151
})
152152

153+
it('automatically insert assetPrefix rewrite for /_next/ paths when assetPrefix is absolute URL with a path', async () => {
154+
const customRoutes = await loadCustomRoutes({
155+
assetPrefix: 'https://example.com/custom-asset-prefix',
156+
})
157+
expect(customRoutes.rewrites.beforeFiles).toEqual([
158+
{
159+
destination: '/_next/:path+',
160+
source: '/custom-asset-prefix/_next/:path+',
161+
},
162+
])
163+
expect(customRoutes.rewrites.afterFiles).toEqual([])
164+
})
165+
153166
it('does not add rewrite when assetPrefix === basePath', async () => {
154167
const customRoutes = await loadCustomRoutes({
155168
assetPrefix: '/base',

packages/next/src/lib/load-custom-routes.ts

+21-12
Original file line numberDiff line numberDiff line change
@@ -596,19 +596,28 @@ async function loadRewrites(config: NextConfig) {
596596
// If assetPrefix is set, add a rewrite for `/${assetPrefix}/_next/*`
597597
// requests so that they are handled in any of dev, start, or deploy
598598
// automatically without the user having to configure this.
599-
// If the assetPrefix is an absolute URL, we can't add an automatic rewrite.
599+
// If the assetPrefix is an absolute URL, we still consider the path for automatic rewrite.
600+
// but hostname routing must be handled by the user
600601
let maybeAssetPrefixRewrite: Rewrite[] = []
601-
if (config.assetPrefix && !isFullStringUrl(config.assetPrefix)) {
602-
const assetPrefix = config.assetPrefix.startsWith('/')
603-
? config.assetPrefix
604-
: `/${config.assetPrefix}`
605-
const basePath = config.basePath || ''
606-
// If these are the same, then this would result in an infinite rewrite.
607-
if (assetPrefix !== basePath) {
608-
maybeAssetPrefixRewrite.push({
609-
source: `${assetPrefix}/_next/:path+`,
610-
destination: `${basePath}/_next/:path+`,
611-
})
602+
if (config.assetPrefix) {
603+
let prefix = config.assetPrefix
604+
if (
605+
isFullStringUrl(config.assetPrefix) &&
606+
URL.canParse(config.assetPrefix)
607+
) {
608+
prefix = new URL(config.assetPrefix).pathname
609+
}
610+
611+
if (prefix && prefix !== '/') {
612+
const assetPrefix = prefix.startsWith('/') ? prefix : `/${prefix}`
613+
const basePath = config.basePath || ''
614+
// If these are the same, then this would result in an infinite rewrite.
615+
if (assetPrefix !== basePath) {
616+
maybeAssetPrefixRewrite.push({
617+
source: `${assetPrefix}/_next/:path+`,
618+
destination: `${basePath}/_next/:path+`,
619+
})
620+
}
612621
}
613622
}
614623

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export default function Root({ children }) {
2+
return (
3+
<html>
4+
<head>
5+
<title>Hello</title>
6+
</head>
7+
<body>{children}</body>
8+
</html>
9+
)
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default function HomePage() {
2+
return <p>Hello world</p>
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { nextTestSetup } from 'e2e-utils'
2+
3+
describe('app-dir absolute assetPrefix', () => {
4+
const { next } = nextTestSetup({
5+
files: __dirname,
6+
})
7+
8+
it('bundles should return 200 on served assetPrefix', async () => {
9+
const $ = await next.render$('/')
10+
11+
let bundles = []
12+
for (const script of $('script').toArray()) {
13+
const { src } = script.attribs
14+
if (
15+
src?.includes(
16+
'https://example.vercel.sh/custom-asset-prefix/_next/static'
17+
)
18+
) {
19+
bundles.push(src)
20+
}
21+
}
22+
23+
expect(bundles.length).toBeGreaterThan(0)
24+
25+
for (const src of bundles) {
26+
// Remove hostname to check if pathname is still used for serving the bundles
27+
const bundlePathWithoutHost = decodeURI(new URL(src).pathname)
28+
const { status } = await next.fetch(bundlePathWithoutHost)
29+
30+
expect(status).toBe(200)
31+
}
32+
})
33+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = {
2+
assetPrefix: 'https://example.vercel.sh/custom-asset-prefix',
3+
}

0 commit comments

Comments
 (0)