Skip to content

Commit

Permalink
Fix twitter metadata info merging (#47433)
Browse files Browse the repository at this point in the history
* Fix rest of twitter metadata when merging with static metadata images,
should include title/description/etc. properties
* rename `opengraph` to `openGraph` property

Related to NEXT-266
Follow up for #47425 

Fixing the twitter metadata are missing found while testing
<img width="583" alt="image"
src="https://user-images.githubusercontent.com/4800338/227190635-60867873-d3b5-4bdc-ab5a-24abdded8faa.png">
  • Loading branch information
huozhi committed Mar 23, 2023
1 parent 0416bd5 commit b2ca7a3
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 41 deletions.
12 changes: 6 additions & 6 deletions packages/next/src/build/webpack/loaders/metadata/discover.ts
Expand Up @@ -23,7 +23,7 @@ export const STATIC_METADATA_IMAGES = {
filename: 'favicon',
extensions: ['ico'],
},
opengraph: {
openGraph: {
filename: 'opengraph-image',
extensions: ['jpg', 'jpeg', 'png', 'gif'],
},
Expand Down Expand Up @@ -94,7 +94,7 @@ export async function createStaticMetadataFromRoute(
icon: [],
apple: [],
twitter: [],
opengraph: [],
openGraph: [],
}

const opts = {
Expand Down Expand Up @@ -131,7 +131,7 @@ export async function createStaticMetadataFromRoute(
}
if (size) {
${
type === 'twitter' || type === 'opengraph'
type === 'twitter' || type === 'openGraph'
? 'props.width = size.width; props.height = size.height;'
: 'props.sizes = size.width + "x" + size.height;'
}
Expand All @@ -142,7 +142,7 @@ export async function createStaticMetadataFromRoute(
`next-metadata-image-loader?${stringify({
route,
numericSizes:
type === 'twitter' || type === 'opengraph' ? '1' : undefined,
type === 'twitter' || type === 'openGraph' ? '1' : undefined,
type,
})}!` +
filepath +
Expand All @@ -161,7 +161,7 @@ export async function createStaticMetadataFromRoute(
await Promise.all([
collectIconModuleIfExists('icon'),
collectIconModuleIfExists('apple'),
collectIconModuleIfExists('opengraph'),
collectIconModuleIfExists('openGraph'),
collectIconModuleIfExists('twitter'),
isRootLayer && collectIconModuleIfExists('favicon'),
])
Expand All @@ -176,7 +176,7 @@ export function createMetadataExportsCode(
? `${METADATA_TYPE}: {
icon: [${metadata.icon.join(',')}],
apple: [${metadata.apple.join(',')}],
opengraph: [${metadata.opengraph.join(',')}],
openGraph: [${metadata.openGraph.join(',')}],
twitter: [${metadata.twitter.join(',')}],
}`
: ''
Expand Down
6 changes: 3 additions & 3 deletions packages/next/src/build/webpack/loaders/metadata/types.ts
Expand Up @@ -10,15 +10,15 @@ export type CollectingMetadata = {
icon: string[]
apple: string[]
twitter: string[]
opengraph: string[]
openGraph: string[]
}

// Contain the collecting evaluated image module
export type CollectedMetadata = {
icon: ComponentModule[]
apple: ComponentModule[]
twitter: ComponentModule[] | null
opengraph: ComponentModule[] | null
openGraph: ComponentModule[] | null
}

export type MetadataImageModule = {
Expand All @@ -37,4 +37,4 @@ export type PossibleImageFileNameConvention =
| 'apple'
| 'favicon'
| 'twitter'
| 'opengraph'
| 'openGraph'
4 changes: 2 additions & 2 deletions packages/next/src/lib/metadata/is-metadata-route.ts
Expand Up @@ -63,10 +63,10 @@ export function isMetadataRouteFile(
}`
),
new RegExp(
`[\\\\/]${STATIC_METADATA_IMAGES.opengraph.filename}${
`[\\\\/]${STATIC_METADATA_IMAGES.openGraph.filename}${
withExtension
? `\\.${getExtensionRegexString(
pageExtensions.concat(STATIC_METADATA_IMAGES.opengraph.extensions)
pageExtensions.concat(STATIC_METADATA_IMAGES.openGraph.extensions)
)}`
: ''
}`
Expand Down
30 changes: 12 additions & 18 deletions packages/next/src/lib/metadata/resolve-metadata.ts
Expand Up @@ -27,6 +27,8 @@ import {
import { resolveIcons } from './resolvers/resolve-icons'
import { getTracer } from '../../server/lib/trace/tracer'
import { ResolveMetadataSpan } from '../../server/lib/trace/constants'
import { Twitter } from './types/twitter-types'
import { OpenGraph } from './types/opengraph-types'

type StaticMetadata = Awaited<ReturnType<typeof resolveStaticMetadata>>

Expand All @@ -43,35 +45,27 @@ function mergeStaticMetadata(
staticFilesMetadata: StaticMetadata
) {
if (!staticFilesMetadata) return
const { icon, apple, opengraph, twitter } = staticFilesMetadata
const { icon, apple, openGraph, twitter } = staticFilesMetadata
if (icon || apple) {
// if (!metadata.icons)
metadata.icons = {
icon: icon || [],
apple: apple || [],
}
// if (icon) metadata.icons.icon.push(...icon)
// if (apple) metadata.icons.apple.push(...apple)
}
if (twitter) {
const resolvedTwitter = resolveTwitter(
{
card: 'summary_large_image',
images: twitter,
},
{ ...metadata.twitter, images: twitter } as Twitter,
metadata.metadataBase
)
metadata.twitter = { ...metadata.twitter, ...resolvedTwitter! }
metadata.twitter = resolvedTwitter
}

if (opengraph) {
const resolvedOg = resolveOpenGraph(
{
images: opengraph,
},
if (openGraph) {
const resolvedOpenGraph = resolveOpenGraph(
{ ...metadata.openGraph, images: openGraph } as OpenGraph,
metadata.metadataBase
)
metadata.openGraph = { ...metadata.openGraph, ...resolvedOg! }
metadata.openGraph = resolvedOpenGraph
}

return metadata
Expand Down Expand Up @@ -229,17 +223,17 @@ async function resolveStaticMetadata(components: ComponentsType) {
const { metadata } = components
if (!metadata) return null

const [icon, apple, opengraph, twitter] = await Promise.all([
const [icon, apple, openGraph, twitter] = await Promise.all([
collectStaticImagesFiles(metadata, 'icon'),
collectStaticImagesFiles(metadata, 'apple'),
collectStaticImagesFiles(metadata, 'opengraph'),
collectStaticImagesFiles(metadata, 'openGraph'),
collectStaticImagesFiles(metadata, 'twitter'),
])

const staticMetadata = {
icon,
apple,
opengraph,
openGraph,
twitter,
}

Expand Down
16 changes: 6 additions & 10 deletions packages/next/src/lib/metadata/resolvers/resolve-opengraph.ts
Expand Up @@ -121,31 +121,27 @@ export const resolveTwitter: FieldResolverWithMetadataBase<'twitter'> = (
) => {
if (!twitter) return null
const resolved = {
title: twitter.title,
...twitter,
card: 'card' in twitter ? twitter.card : 'summary',
} as ResolvedTwitterMetadata
for (const infoKey of TwitterBasicInfoKeys) {
resolved[infoKey] = twitter[infoKey] || null
}
resolved.images = resolveImages(twitter.images, metadataBase)

if ('card' in twitter) {
resolved.card = twitter.card
switch (twitter.card) {
if ('card' in resolved) {
switch (resolved.card) {
case 'player': {
// @ts-ignore
resolved.players = resolveAsArrayOrUndefined(twitter.players) || []
resolved.players = resolveAsArrayOrUndefined(resolved.players) || []
break
}
case 'app': {
// @ts-ignore
resolved.app = twitter.app || {}
resolved.app = resolved.app || {}
break
}
default:
break
}
} else {
resolved.card = 'summary'
}

return resolved
Expand Down
9 changes: 7 additions & 2 deletions test/e2e/app-dir/metadata-dynamic-routes/app/layout.tsx
Expand Up @@ -8,6 +8,11 @@ export default function Layout({ children }) {
}

export const metadata = {
title: 'this is the layout title',
description: 'this is the layout description',
title: 'Next.js App',
description: 'This is a Next.js App',
twitter: {
cardType: 'summary_large_image',
title: 'Twitter - Next.js App',
description: 'Twitter - This is a Next.js App',
},
}
8 changes: 8 additions & 0 deletions test/e2e/app-dir/metadata-dynamic-routes/index.test.ts
Expand Up @@ -151,6 +151,10 @@ createNextDescribe(
const $appleIcon = $('link[rel="apple-touch-icon"]')
const ogImageUrl = $('meta[property="og:image"]').attr('content')
const twitterImageUrl = $('meta[name="twitter:image"]').attr('content')
const twitterTitle = $('meta[name="twitter:title"]').attr('content')
const twitterDescription = $('meta[name="twitter:description"]').attr(
'content'
)

// non absolute urls
expect($icon.attr('href')).toBe('/icon')
Expand All @@ -160,6 +164,10 @@ createNextDescribe(
expect($appleIcon.attr('sizes')).toBe(undefined)
expect($appleIcon.attr('type')).toBe('image/png')

// Twitter
expect(twitterTitle).toBe('Twitter - Next.js App')
expect(twitterDescription).toBe('Twitter - This is a Next.js App')

// absolute urls
expect(ogImageUrl).toBe(
'https://deploy-preview-abc.vercel.app/opengraph-image'
Expand Down
6 changes: 6 additions & 0 deletions test/e2e/app-dir/metadata/app/opengraph/static/page.tsx
@@ -1,3 +1,9 @@
export default function Page() {
return 'opengraph-static'
}

export const metadata = {
twitter: {
card: 'summary_large_image',
},
}

0 comments on commit b2ca7a3

Please sign in to comment.