Skip to content

Commit

Permalink
Fix missing metadataBase for static tw,og image resolving (#46243)
Browse files Browse the repository at this point in the history
Replacement for #46156
Closes NEXT-587

* `metadataBase` will always need to be provided for twitter image and
opengraph image
* Fixing the metadataBase isn't picked up by static og/twitter images

## Bug

- [x] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Errors have a helpful link attached, see
[`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md)
  • Loading branch information
huozhi authored Feb 22, 2023
1 parent e09feab commit 65ecd9c
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 22 deletions.
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

0 comments on commit 65ecd9c

Please sign in to comment.