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

fix: absolute assetPrefix url with path #77256

Merged
merged 7 commits into from
Mar 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion packages/next/src/lib/load-custom-routes.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,12 +144,25 @@ describe('loadCustomRoutes', () => {

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

it('automatically insert assetPrefix rewrite for /_next/ paths when assetPrefix is absolute URL with a path', async () => {
const customRoutes = await loadCustomRoutes({
assetPrefix: 'https://example.com/custom-asset-prefix',
})
expect(customRoutes.rewrites.beforeFiles).toEqual([
{
destination: '/_next/:path+',
source: '/custom-asset-prefix/_next/:path+',
},
])
expect(customRoutes.rewrites.afterFiles).toEqual([])
})

it('does not add rewrite when assetPrefix === basePath', async () => {
const customRoutes = await loadCustomRoutes({
assetPrefix: '/base',
Expand Down
33 changes: 21 additions & 12 deletions packages/next/src/lib/load-custom-routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -596,19 +596,28 @@ async function loadRewrites(config: NextConfig) {
// If assetPrefix is set, add a rewrite for `/${assetPrefix}/_next/*`
// requests so that they are handled in any of dev, start, or deploy
// automatically without the user having to configure this.
// If the assetPrefix is an absolute URL, we can't add an automatic rewrite.
// If the assetPrefix is an absolute URL, we still consider the path for automatic rewrite.
// but hostname routing must be handled by the user
let maybeAssetPrefixRewrite: Rewrite[] = []
if (config.assetPrefix && !isFullStringUrl(config.assetPrefix)) {
const assetPrefix = config.assetPrefix.startsWith('/')
? config.assetPrefix
: `/${config.assetPrefix}`
const basePath = config.basePath || ''
// If these are the same, then this would result in an infinite rewrite.
if (assetPrefix !== basePath) {
maybeAssetPrefixRewrite.push({
source: `${assetPrefix}/_next/:path+`,
destination: `${basePath}/_next/:path+`,
})
if (config.assetPrefix) {
let prefix = config.assetPrefix
if (
isFullStringUrl(config.assetPrefix) &&
URL.canParse(config.assetPrefix)
) {
prefix = new URL(config.assetPrefix).pathname
}

if (prefix && prefix !== '/') {
const assetPrefix = prefix.startsWith('/') ? prefix : `/${prefix}`
const basePath = config.basePath || ''
// If these are the same, then this would result in an infinite rewrite.
if (assetPrefix !== basePath) {
maybeAssetPrefixRewrite.push({
source: `${assetPrefix}/_next/:path+`,
destination: `${basePath}/_next/:path+`,
})
}
}
}

Expand Down
10 changes: 10 additions & 0 deletions test/e2e/app-dir/asset-prefix-absolute/app/layout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export default function Root({ children }) {
return (
<html>
<head>
<title>Hello</title>
</head>
<body>{children}</body>
</html>
)
}
3 changes: 3 additions & 0 deletions test/e2e/app-dir/asset-prefix-absolute/app/page.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function HomePage() {
return <p>Hello world</p>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { nextTestSetup } from 'e2e-utils'

describe('app-dir absolute assetPrefix', () => {
const { next } = nextTestSetup({
files: __dirname,
})

it('bundles should return 200 on served assetPrefix', async () => {
const $ = await next.render$('/')

let bundles = []
for (const script of $('script').toArray()) {
const { src } = script.attribs
if (
src?.includes(
'https://example.vercel.sh/custom-asset-prefix/_next/static'
)
) {
bundles.push(src)
}
}

expect(bundles.length).toBeGreaterThan(0)

for (const src of bundles) {
// Remove hostname to check if pathname is still used for serving the bundles
const bundlePathWithoutHost = decodeURI(new URL(src).pathname)
const { status } = await next.fetch(bundlePathWithoutHost)

expect(status).toBe(200)
}
})
})
3 changes: 3 additions & 0 deletions test/e2e/app-dir/asset-prefix-absolute/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
assetPrefix: 'https://example.vercel.sh/custom-asset-prefix',
}
Loading