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 missing metadataBase for static tw,og image resolving #46243

Merged
merged 2 commits into from
Feb 22, 2023
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
6 changes: 3 additions & 3 deletions packages/next/src/lib/metadata/resolve-metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ function mergeStaticMetadata(
card: 'summary_large_image',
images: twitter,
},
null
metadata.metadataBase
)
metadata.twitter = { ...metadata.twitter, ...resolvedTwitter! }
}
Expand All @@ -62,7 +62,7 @@ function mergeStaticMetadata(
{
images: opengraph,
},
null
metadata.metadataBase
)
metadata.openGraph = { ...metadata.openGraph, ...resolvedOg! }
}
Expand All @@ -81,7 +81,7 @@ function merge(
openGraph: string | null
}
) {
const metadataBase = source?.metadataBase || null
const metadataBase = source?.metadataBase || target.metadataBase
for (const key_ in source) {
const key = key_ as keyof Metadata

Expand Down
47 changes: 33 additions & 14 deletions packages/next/src/lib/metadata/resolvers/resolve-opengraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import type {
ResolvedOpenGraph,
} from '../types/opengraph-types'
import type { FieldResolverWithMetadataBase } from '../types/resolvers'
import type { ResolvedTwitterMetadata } from '../types/twitter-types'
import type { ResolvedTwitterMetadata, Twitter } from '../types/twitter-types'
import { resolveAsArrayOrUndefined } from '../generate/utils'
import { isStringOrURL, resolveUrl } from './resolve-url'

Expand All @@ -25,6 +25,34 @@ const OgTypFields = {
],
} as const

function resolveImages(
images: Twitter['images'],
metadataBase: ResolvedMetadata['metadataBase']
): NonNullable<ResolvedMetadata['twitter']>['images']
function resolveImages(
images: OpenGraph['images'],
metadataBase: ResolvedMetadata['metadataBase']
): NonNullable<ResolvedMetadata['openGraph']>['images']
function resolveImages(
images: OpenGraph['images'] | Twitter['images'],
metadataBase: ResolvedMetadata['metadataBase']
):
| NonNullable<ResolvedMetadata['twitter']>['images']
| NonNullable<ResolvedMetadata['openGraph']>['images'] {
const resolvedImages = resolveAsArrayOrUndefined(images)
resolvedImages?.forEach((item, index, array) => {
if (isStringOrURL(item)) {
array[index] = {
url: metadataBase ? resolveUrl(item, metadataBase)! : item,
}
} else {
// Update image descriptor url
item.url = metadataBase ? resolveUrl(item.url, metadataBase)! : item.url
}
})
return resolvedImages
}

function getFieldsByOgType(ogType: OpenGraphType | undefined) {
switch (ogType) {
case 'article':
Expand Down Expand Up @@ -68,7 +96,8 @@ export function resolveOpenGraph(
}
}
}
resolved.images = resolveAsArrayOrUndefined(og.images)

resolved.images = resolveImages(og.images, metadataBase)
}

assignProps(openGraph)
Expand Down Expand Up @@ -97,18 +126,8 @@ export const resolveTwitter: FieldResolverWithMetadataBase<'twitter'> = (
for (const infoKey of TwitterBasicInfoKeys) {
resolved[infoKey] = twitter[infoKey] || null
}
resolved.images = resolveAsArrayOrUndefined(twitter.images)?.map((item) => {
if (isStringOrURL(item))
return {
url: metadataBase ? resolveUrl(item, metadataBase) : item,
}
else {
return {
url: metadataBase ? resolveUrl(item.url, metadataBase) : item.url,
alt: item.alt,
}
}
})
resolved.images = resolveImages(twitter.images, metadataBase)

if ('card' in twitter) {
resolved.card = twitter.card
switch (twitter.card) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ describe('metadata: resolveUrl', () => {
})

it('should error when metadataBase is not provided but url is not valid URL', () => {
expect(() => resolveUrl('/abc', null)).toThrow('missing metadataBase')
expect(() => resolveUrl('/abc', null)).toThrow()
})

it('should return url itself when metadataBase is null or url is valid URL', () => {
Expand Down
5 changes: 4 additions & 1 deletion packages/next/src/lib/metadata/resolvers/resolve-url.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ function resolveUrl(
return parsedUrl
} catch (_) {}

if (!metadataBase) throw new Error('missing metadataBase')
if (!metadataBase)
throw new Error(
`metadata.metadataBase needs to be provided for resolving absolute URLs: ${url}`
)

// Handle relative or absolute paths
const basePath = metadataBase.pathname || '/'
Expand Down
6 changes: 5 additions & 1 deletion packages/next/src/lib/metadata/types/twitter-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,12 @@ type TwitterPlayerDescriptor = {
}

type ResolvedTwitterImage = {
url: null | URL | string
url: string | URL
alt?: string
secureUrl?: string | URL
type?: string
width?: string | number
height?: string | number
}
type ResolvedTwitterSummary = {
site: string | null
Expand Down
7 changes: 7 additions & 0 deletions test/e2e/app-dir/metadata/app/opengraph/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default function Layout({ children }) {
return children
}

export const metadata = {
metadataBase: new URL('https://example.com/'),
}
4 changes: 2 additions & 2 deletions test/e2e/app-dir/metadata/metadata.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ createNextDescribe(
it('should pick up opengraph-image and twitter-image as static metadata files', async () => {
const $ = await next.render$('/opengraph/static')
expect($('[property="og:image:url"]').attr('content')).toMatch(
/_next\/static\/media\/metadata\/opengraph-image.\w+.png/
/https:\/\/example.com\/_next\/static\/media\/metadata\/opengraph-image.\w+.png/
)
expect($('[property="og:image:type"]').attr('content')).toBe(
'image/png'
Expand All @@ -459,7 +459,7 @@ createNextDescribe(
expect($('[property="og:image:height"]').attr('content')).toBe('114')

expect($('[name="twitter:image"]').attr('content')).toMatch(
/_next\/static\/media\/metadata\/twitter-image.\w+.png/
/https:\/\/example.com\/_next\/static\/media\/metadata\/twitter-image.\w+.png/
)
expect($('[name="twitter:card"]').attr('content')).toBe(
'summary_large_image'
Expand Down