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

Use vercel deployment url for metadataBase fallbacks #65089

Merged
merged 5 commits into from Apr 29, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
74 changes: 73 additions & 1 deletion packages/next/src/lib/metadata/resolvers/resolve-url.test.ts
@@ -1,4 +1,8 @@
import { resolveUrl, resolveAbsoluteUrlWithPathname } from './resolve-url'
import {
resolveUrl,
resolveAbsoluteUrlWithPathname,
getSocialImageFallbackMetadataBase,
} from './resolve-url'

// required to be resolved as URL with resolveUrl()
describe('metadata: resolveUrl', () => {
Expand Down Expand Up @@ -106,3 +110,71 @@ describe('resolveAbsoluteUrlWithPathname', () => {
})
})
})

describe('getSocialImageFallbackMetadataBase', () => {
describe('fallbackMetadataBase', () => {
let originalEnv: NodeJS.ProcessEnv
function getSocialImageFallbackMetadataBaseHelper(): string {
return getSocialImageFallbackMetadataBase(null).fallbackMetadataBase.href
}

beforeEach(() => {
originalEnv = process.env
})

afterEach(() => {
delete process.env.VERCEL_URL
delete process.env.VERCEL_ENV
delete process.env.VERCEL_BRANCH_URL
delete process.env.VERCEL_PROJECT_PRODUCTION_URL

process.env = originalEnv
})

it('should return localhost url in local dev mode', () => {
// @ts-expect-error override process env
process.env.NODE_ENV = 'development'
expect(getSocialImageFallbackMetadataBaseHelper()).toBe(
'http://localhost:3000/'
)
})

it('should return metadataBase ', () => {
// @ts-expect-error override process env
process.env.NODE_ENV = 'production'
expect(getSocialImageFallbackMetadataBaseHelper()).toBe(
'http://localhost:3000/'
)
huozhi marked this conversation as resolved.
Show resolved Hide resolved
})

it('should prefer branch url in preview deployment if presents', () => {
// @ts-expect-error override process env
process.env.NODE_ENV = 'production'
process.env.VERCEL_ENV = 'preview'
process.env.VERCEL_BRANCH_URL = 'branch-url'
process.env.VERCEL_URL = 'vercel-url'
expect(getSocialImageFallbackMetadataBaseHelper()).toBe(
'https://branch-url/'
)
})

it('should return vercel url in preview deployment if only it presents', () => {
// @ts-expect-error override process env
process.env.NODE_ENV = 'production'
process.env.VERCEL_ENV = 'preview'
process.env.VERCEL_URL = 'vercel-url'
expect(getSocialImageFallbackMetadataBaseHelper()).toBe(
'https://vercel-url/'
)
})

it('should return project production url in production deployment', () => {
// @ts-expect-error override process env
process.env.NODE_ENV = 'production'
process.env.VERCEL_PROJECT_PRODUCTION_URL = 'production-url'
expect(getSocialImageFallbackMetadataBaseHelper()).toBe(
'https://production-url/'
)
})
})
})
huozhi marked this conversation as resolved.
Show resolved Hide resolved
20 changes: 15 additions & 5 deletions packages/next/src/lib/metadata/resolvers/resolve-url.ts
Expand Up @@ -9,6 +9,16 @@ function createLocalMetadataBase() {
return new URL(`http://localhost:${process.env.PORT || 3000}`)
}

function getPreviewDeploymentUrl(): URL | undefined {
const origin = process.env.VERCEL_BRANCH_URL || process.env.VERCEL_URL
return origin ? new URL(`https://${origin}`) : undefined
}

function getProductionDeploymentUrl(): URL | undefined {
const origin = process.env.VERCEL_PROJECT_PRODUCTION_URL
return origin ? new URL(`https://${origin}`) : undefined
}

// For deployment url for metadata routes, prefer to use the deployment url if possible
// as these routes are unique to the deployments url.
export function getSocialImageFallbackMetadataBase(metadataBase: URL | null): {
Expand All @@ -17,19 +27,19 @@ export function getSocialImageFallbackMetadataBase(metadataBase: URL | null): {
} {
const isMetadataBaseMissing = !metadataBase
const defaultMetadataBase = createLocalMetadataBase()
const deploymentUrl =
process.env.VERCEL_URL && new URL(`https://${process.env.VERCEL_URL}`)
const previewDeploymentUrl = getPreviewDeploymentUrl()
const productionDeploymentUrl = getProductionDeploymentUrl()

let fallbackMetadataBase
if (process.env.NODE_ENV === 'development') {
fallbackMetadataBase = defaultMetadataBase
} else {
fallbackMetadataBase =
process.env.NODE_ENV === 'production' &&
deploymentUrl &&
previewDeploymentUrl &&
process.env.VERCEL_ENV === 'preview'
? deploymentUrl
: metadataBase || deploymentUrl || defaultMetadataBase
? previewDeploymentUrl
: metadataBase || productionDeploymentUrl || defaultMetadataBase
}

return {
Expand Down