diff --git a/contributing/repository/linting.md b/contributing/repository/linting.md index 30535fdd6d0cf..08af8ecfdb7ae 100644 --- a/contributing/repository/linting.md +++ b/contributing/repository/linting.md @@ -30,7 +30,7 @@ We recommend installing the [Prettier plugin for VS Code](https://marketplace.vi You can find the format configuration in the [Prettier config](../../.prettierrc.json). -## alex +## Alex We recommend installing the [AlexJS Linter extension for VSCode](https://marketplace.visualstudio.com/items?itemName=TLahmann.alex-linter) diff --git a/docs/02-app/02-api-reference/04-functions/generate-metadata.mdx b/docs/02-app/02-api-reference/04-functions/generate-metadata.mdx index 570f5b00ddb54..704f93b6d8d1c 100644 --- a/docs/02-app/02-api-reference/04-functions/generate-metadata.mdx +++ b/docs/02-app/02-api-reference/04-functions/generate-metadata.mdx @@ -927,6 +927,20 @@ export const metadata = { ``` +### `facebook` + +```jsx filename="layout.js | page.js" +export const metadata = { + facebook: { + appId: '12345678', + }, +} +``` + +```html filename="
output" hideLineNumbers + +``` + ### `other` All metadata options should be covered using the built-in support. However, there may be custom metadata tags specific to your site, or brand new metadata tags just released. You can use the `other` option to render any custom metadata tag. diff --git a/packages/next/src/lib/metadata/default-metadata.tsx b/packages/next/src/lib/metadata/default-metadata.tsx index 75207ea6fea35..2449688350c52 100644 --- a/packages/next/src/lib/metadata/default-metadata.tsx +++ b/packages/next/src/lib/metadata/default-metadata.tsx @@ -47,6 +47,7 @@ export function createDefaultMetadata(): ResolvedMetadata { appleWebApp: null, formatDetection: null, itunes: null, + facebook: null, abstract: null, appLinks: null, archives: null, diff --git a/packages/next/src/lib/metadata/generate/basic.tsx b/packages/next/src/lib/metadata/generate/basic.tsx index 1d9dfb40200d6..f593a991a5eb0 100644 --- a/packages/next/src/lib/metadata/generate/basic.tsx +++ b/packages/next/src/lib/metadata/generate/basic.tsx @@ -125,6 +125,16 @@ export function ItunesMeta({ itunes }: { itunes: ResolvedMetadata['itunes'] }) { return } +export function FacebookMeta({ + facebook, +}: { + facebook: ResolvedMetadata['facebook'] +}) { + if (!facebook) return null + const { appId } = facebook + return +} + const formatDetectionKeys = [ 'telephone', 'date', diff --git a/packages/next/src/lib/metadata/metadata.tsx b/packages/next/src/lib/metadata/metadata.tsx index 35be61e61b74b..c565790d3fdba 100644 --- a/packages/next/src/lib/metadata/metadata.tsx +++ b/packages/next/src/lib/metadata/metadata.tsx @@ -10,6 +10,7 @@ import { BasicMeta, ViewportMeta, VerificationMeta, + FacebookMeta, } from './generate/basic' import { AlternatesMetadata } from './generate/alternate' import { @@ -124,6 +125,7 @@ export function createMetadataComponents({ BasicMeta({ metadata }), AlternatesMetadata({ alternates: metadata.alternates }), ItunesMeta({ itunes: metadata.itunes }), + FacebookMeta({ facebook: metadata.facebook }), FormatDetectionMeta({ formatDetection: metadata.formatDetection }), VerificationMeta({ verification: metadata.verification }), AppleWebAppMeta({ appleWebApp: metadata.appleWebApp }), diff --git a/packages/next/src/lib/metadata/resolve-metadata.ts b/packages/next/src/lib/metadata/resolve-metadata.ts index ca6d6685ff8db..bd663d04d897d 100644 --- a/packages/next/src/lib/metadata/resolve-metadata.ts +++ b/packages/next/src/lib/metadata/resolve-metadata.ts @@ -37,6 +37,7 @@ import { resolveThemeColor, resolveVerification, resolveItunes, + resolveFacebook, } from './resolvers/resolve-basics' import { resolveIcons } from './resolvers/resolve-icons' import { getTracer } from '../../server/lib/trace/tracer' @@ -196,6 +197,10 @@ function mergeMetadata({ ) break } + case 'facebook': + target.facebook = resolveFacebook(source.facebook) + break + case 'verification': target.verification = resolveVerification(source.verification) break diff --git a/packages/next/src/lib/metadata/resolvers/resolve-basics.ts b/packages/next/src/lib/metadata/resolvers/resolve-basics.ts index 591549b910205..24fbcafba046c 100644 --- a/packages/next/src/lib/metadata/resolvers/resolve-basics.ts +++ b/packages/next/src/lib/metadata/resolvers/resolve-basics.ts @@ -255,3 +255,10 @@ export const resolveItunes: FieldResolverExtraArgs< : undefined, } } + +export const resolveFacebook: FieldResolver<'facebook'> = (facebook) => { + if (!facebook) return null + return { + appId: facebook.appId, + } +} diff --git a/packages/next/src/lib/metadata/types/extra-types.ts b/packages/next/src/lib/metadata/types/extra-types.ts index 514ad9b507cf2..2384066485fb5 100644 --- a/packages/next/src/lib/metadata/types/extra-types.ts +++ b/packages/next/src/lib/metadata/types/extra-types.ts @@ -88,6 +88,10 @@ export type ResolvedAppleWebApp = { statusBarStyle?: 'default' | 'black' | 'black-translucent' } +export type Facebook = { + appId?: string +} + // Format Detection // This is a poorly specified metadata export type that is supposed to // control whether the device attempts to conver text that matches diff --git a/packages/next/src/lib/metadata/types/metadata-interface.ts b/packages/next/src/lib/metadata/types/metadata-interface.ts index a840df2dfae37..dcf7d5c83f4c6 100644 --- a/packages/next/src/lib/metadata/types/metadata-interface.ts +++ b/packages/next/src/lib/metadata/types/metadata-interface.ts @@ -6,6 +6,7 @@ import type { import type { AppleWebApp, AppLinks, + Facebook, FormatDetection, ItunesApp, ResolvedAppleWebApp, @@ -320,6 +321,18 @@ interface Metadata extends DeprecatedMetadataFields { */ twitter?: null | Twitter + /** + * The Facebook metadata for the document. + * @example + * ```tsx + * { appId: "12345678" } + * + * + * ``` + * + */ + facebook?: null | Facebook + /** * The common verification tokens for the document. * @example @@ -508,6 +521,8 @@ interface ResolvedMetadata extends DeprecatedMetadataFields { twitter: null | ResolvedTwitterMetadata + facebook: null | Facebook + // common verification tokens verification: null | ResolvedVerification diff --git a/test/e2e/app-dir/metadata/app/facebook/page.tsx b/test/e2e/app-dir/metadata/app/facebook/page.tsx new file mode 100644 index 0000000000000..f033a9fe78282 --- /dev/null +++ b/test/e2e/app-dir/metadata/app/facebook/page.tsx @@ -0,0 +1,12 @@ +export default function page() { + return 'facebook' +} + +export async function generateMetadata() { + const metadata = { + facebook: { + appId: '12345678', + }, + } + return metadata +} diff --git a/test/e2e/app-dir/metadata/metadata.test.ts b/test/e2e/app-dir/metadata/metadata.test.ts index 797e7863877a9..562f54a53f93a 100644 --- a/test/e2e/app-dir/metadata/metadata.test.ts +++ b/test/e2e/app-dir/metadata/metadata.test.ts @@ -299,6 +299,15 @@ describe('app dir - metadata', () => { ) }) + it('should support facebook related tags', async () => { + const browser = await next.browser('/facebook') + const matchDom = createDomMatcher(browser) + + await matchDom('meta', 'property="fb:app_id"', { + content: '12345678', + }) + }) + it('should support alternate tags', async () => { const browser = await next.browser('/alternates') const matchDom = createDomMatcher(browser)