diff --git a/packages/meta-tags/src/app-router/generate-apple-smart-banner-meta.ts b/packages/meta-tags/src/app-router/generate-apple-smart-banner-meta.ts new file mode 100644 index 0000000000..3ed812fc2d --- /dev/null +++ b/packages/meta-tags/src/app-router/generate-apple-smart-banner-meta.ts @@ -0,0 +1,20 @@ +import { Metadata } from 'next' + +import { DEFAULT_APP_ID } from '../constants' + +export function generateAppleSmartBannerMeta({ + appId = DEFAULT_APP_ID, + appPath = '/', +}: { + appId?: string + appPath?: string +} = {}): Metadata { + const appUrlScheme = process.env.NEXT_PUBLIC_APP_URL_SCHEME || '' + + return { + itunes: { + appId, + appArgument: `${appUrlScheme}://${appPath}`, + }, + } +} diff --git a/packages/meta-tags/src/app-router/generate-common-meta.ts b/packages/meta-tags/src/app-router/generate-common-meta.ts new file mode 100644 index 0000000000..44a67358f7 --- /dev/null +++ b/packages/meta-tags/src/app-router/generate-common-meta.ts @@ -0,0 +1,10 @@ +import { Metadata } from 'next' + +export function generateCommonMeta(): Metadata { + return { + icons: { + apple: 'https://triple.guide/icons/favicon-152x152.png', + }, + manifest: '/manifest.json', + } +} diff --git a/packages/meta-tags/src/app-router/generate-essential-content-meta.ts b/packages/meta-tags/src/app-router/generate-essential-content-meta.ts new file mode 100644 index 0000000000..b30e1f70a0 --- /dev/null +++ b/packages/meta-tags/src/app-router/generate-essential-content-meta.ts @@ -0,0 +1,20 @@ +import { Metadata } from 'next' + +export function generateEssentialContentMeta({ + title, + description, + canonicalUrl, +}: { + title?: string + description?: string + canonicalUrl?: string +} = {}): Metadata { + return { + title: title || process.env.NEXT_PUBLIC_DEFAULT_PAGE_TITLE || '', + description: + description || process.env.NEXT_PUBLIC_DEFAULT_PAGE_DESCRIPTION || '', + alternates: { + canonical: canonicalUrl, + }, + } +} diff --git a/packages/meta-tags/src/app-router/generate-facebook-app-link-meta.ts b/packages/meta-tags/src/app-router/generate-facebook-app-link-meta.ts new file mode 100644 index 0000000000..f418eac44d --- /dev/null +++ b/packages/meta-tags/src/app-router/generate-facebook-app-link-meta.ts @@ -0,0 +1,34 @@ +import { Metadata } from 'next' + +import { DEFAULT_APP_ID, DEFAULT_APP_PACKAGE_NAME } from '../constants' + +export function generateFacebookAppLinkMeta({ + appName: appNameFromProps, + appId = DEFAULT_APP_ID, + appPath = '/', + appPackageName = DEFAULT_APP_PACKAGE_NAME, +}: { + appName?: string + appId?: string + appPath?: string + appPackageName?: string +} = {}): Metadata { + const appName = appNameFromProps ?? '트리플' + const appUrlScheme = process.env.NEXT_PUBLIC_APP_URL_SCHEME || '' + const url = `${appUrlScheme}://${appPath}` + + return { + appLinks: { + ios: { + app_name: appName, + url, + app_store_id: appId, + }, + android: { + app_name: appName, + url, + package: appPackageName, + }, + }, + } +} diff --git a/packages/meta-tags/src/app-router/generate-facebook-open-graph-meta.ts b/packages/meta-tags/src/app-router/generate-facebook-open-graph-meta.ts new file mode 100644 index 0000000000..6bcb1d1b75 --- /dev/null +++ b/packages/meta-tags/src/app-router/generate-facebook-open-graph-meta.ts @@ -0,0 +1,40 @@ +import { Metadata } from 'next' +import { OpenGraphType } from 'next/dist/lib/metadata/types/opengraph-types' + +import { DEFAULT_OG_IMAGE } from '../constants' + +export function generateFacebookOpenGraphMeta({ + title: titleFromProps, + description: descriptionFromProps, + canonicalUrl, + type = 'website', + locale = 'ko_KR', + image = DEFAULT_OG_IMAGE, +}: { + title?: string + description?: string + canonicalUrl?: string + type?: OpenGraphType + locale?: string + image?: { url: string; width?: number; height?: number } +} = {}): Metadata { + const title = titleFromProps || process.env.NEXT_PUBLIC_DEFAULT_PAGE_TITLE + const description = + descriptionFromProps || process.env.NEXT_PUBLIC_DEFAULT_PAGE_DESCRIPTION + const url = + canonicalUrl || + (process.env.NEXT_PUBLIC_WEB_URL_BASE + ? `${process.env.NEXT_PUBLIC_WEB_URL_BASE}/auth-web` + : undefined) + + return { + openGraph: { + title, + description, + url, + type, + locale, + images: image, + }, + } +} diff --git a/packages/meta-tags/src/app-router/generate-triple-default-meta.ts b/packages/meta-tags/src/app-router/generate-triple-default-meta.ts new file mode 100644 index 0000000000..60dea457d4 --- /dev/null +++ b/packages/meta-tags/src/app-router/generate-triple-default-meta.ts @@ -0,0 +1,17 @@ +import { Metadata } from 'next' + +import { generateCommonMeta } from './generate-common-meta' +import { generateEssentialContentMeta } from './generate-essential-content-meta' +import { generateFacebookOpenGraphMeta } from './generate-facebook-open-graph-meta' +import { generateFacebookAppLinkMeta } from './generate-facebook-app-link-meta' +import { generateAppleSmartBannerMeta } from './generate-apple-smart-banner-meta' + +export function generateTripleDefaultMeta(): Metadata { + return { + ...generateCommonMeta(), + ...generateEssentialContentMeta(), + ...generateFacebookOpenGraphMeta(), + ...generateFacebookAppLinkMeta(), + ...generateAppleSmartBannerMeta(), + } +} diff --git a/packages/meta-tags/src/app-router/index.ts b/packages/meta-tags/src/app-router/index.ts new file mode 100644 index 0000000000..a1ddb0fa01 --- /dev/null +++ b/packages/meta-tags/src/app-router/index.ts @@ -0,0 +1,6 @@ +export * from './generate-common-meta' +export * from './generate-apple-smart-banner-meta' +export * from './generate-essential-content-meta' +export * from './generate-facebook-app-link-meta' +export * from './generate-facebook-open-graph-meta' +export * from './generate-triple-default-meta' diff --git a/packages/meta-tags/src/article-script.tsx b/packages/meta-tags/src/article-script.tsx deleted file mode 100644 index 9c8183c001..0000000000 --- a/packages/meta-tags/src/article-script.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import Head from 'next/head' - -import { createScript } from './utils' -import { ArticleScriptProps } from './types' - -export function ArticleScript(props: ArticleScriptProps) { - const articleScript = createScript(props, 'Article') - - return ( -
- - - ) -} diff --git a/packages/meta-tags/src/breadcrumb-list-script.tsx b/packages/meta-tags/src/breadcrumb-list-script.tsx deleted file mode 100644 index b87e0bfa5f..0000000000 --- a/packages/meta-tags/src/breadcrumb-list-script.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import Head from 'next/head' - -import { createScript } from './utils' -import { BreadcrumbListScriptProps } from './types' - -export function BreadcrumbListScript(props: BreadcrumbListScriptProps) { - const breadcrumbScript = createScript(props, 'BreadcrumbList') - - return ( - - - - ) -} diff --git a/packages/meta-tags/src/index.ts b/packages/meta-tags/src/index.ts index 4b38acb35d..b503885307 100644 --- a/packages/meta-tags/src/index.ts +++ b/packages/meta-tags/src/index.ts @@ -1,12 +1,4 @@ -export { ItemAvailability } from './types' -export { EssentialContentMeta } from './essential-content-meta' -export { CommonMeta } from './common-meta' -export { AppleSmartBannerMeta } from './apple-smart-banner-meta' -export { FacebookAppLinkMeta } from './facebook-app-link-meta' -export { FacebookOpenGraphMeta } from './facebook-open-graph-meta' -export { ThemeColorMeta } from './theme-color-meta' -export { ArticleScript } from './article-script' -export { BreadcrumbListScript } from './breadcrumb-list-script' -export { ProductScript } from './product-script' -export { LocalBusinessScript } from './local-business-script' -export { ReviewScript } from './review-script' +export * from './types' +export * from './app-router' +export * from './pages-router' +export * from './structured-data' diff --git a/packages/meta-tags/src/local-business-script.tsx b/packages/meta-tags/src/local-business-script.tsx deleted file mode 100644 index 772ef2adaf..0000000000 --- a/packages/meta-tags/src/local-business-script.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import Head from 'next/head' - -import { SCHEMA_SCRIPT_TYPE_MAP, createScript } from './utils' -import { LocalBusinessScriptProps } from './types' - -export function LocalBusinessScript({ - type, - ...props -}: LocalBusinessScriptProps) { - const localBusinessScript = createScript(props, SCHEMA_SCRIPT_TYPE_MAP[type]) - - return ( - - - - ) -} diff --git a/packages/meta-tags/src/apple-smart-banner-meta.tsx b/packages/meta-tags/src/pages-router/apple-smart-banner-meta.tsx similarity index 90% rename from packages/meta-tags/src/apple-smart-banner-meta.tsx rename to packages/meta-tags/src/pages-router/apple-smart-banner-meta.tsx index d2c7e9f8ca..eb588cc435 100644 --- a/packages/meta-tags/src/apple-smart-banner-meta.tsx +++ b/packages/meta-tags/src/pages-router/apple-smart-banner-meta.tsx @@ -1,7 +1,7 @@ import Head from 'next/head' import { useEnv } from '@titicaca/triple-web' -import { DEFAULT_APP_ID } from './constants' +import { DEFAULT_APP_ID } from '../constants' export function AppleSmartBannerMeta({ appId = DEFAULT_APP_ID, diff --git a/packages/meta-tags/src/common-meta.tsx b/packages/meta-tags/src/pages-router/common-meta.tsx similarity index 100% rename from packages/meta-tags/src/common-meta.tsx rename to packages/meta-tags/src/pages-router/common-meta.tsx diff --git a/packages/meta-tags/src/essential-content-meta.test.tsx b/packages/meta-tags/src/pages-router/essential-content-meta.test.tsx similarity index 100% rename from packages/meta-tags/src/essential-content-meta.test.tsx rename to packages/meta-tags/src/pages-router/essential-content-meta.test.tsx diff --git a/packages/meta-tags/src/essential-content-meta.tsx b/packages/meta-tags/src/pages-router/essential-content-meta.tsx similarity index 100% rename from packages/meta-tags/src/essential-content-meta.tsx rename to packages/meta-tags/src/pages-router/essential-content-meta.tsx diff --git a/packages/meta-tags/src/facebook-app-link-meta.tsx b/packages/meta-tags/src/pages-router/facebook-app-link-meta.tsx similarity index 94% rename from packages/meta-tags/src/facebook-app-link-meta.tsx rename to packages/meta-tags/src/pages-router/facebook-app-link-meta.tsx index 05d4b1c5ed..9db3d7a0e9 100644 --- a/packages/meta-tags/src/facebook-app-link-meta.tsx +++ b/packages/meta-tags/src/pages-router/facebook-app-link-meta.tsx @@ -1,7 +1,7 @@ import Head from 'next/head' import { useEnv, useTranslation } from '@titicaca/triple-web' -import { DEFAULT_APP_ID, DEFAULT_APP_PACKAGE_NAME } from './constants' +import { DEFAULT_APP_ID, DEFAULT_APP_PACKAGE_NAME } from '../constants' export function FacebookAppLinkMeta({ appName, diff --git a/packages/meta-tags/src/facebook-open-graph-meta.tsx b/packages/meta-tags/src/pages-router/facebook-open-graph-meta.tsx similarity index 97% rename from packages/meta-tags/src/facebook-open-graph-meta.tsx rename to packages/meta-tags/src/pages-router/facebook-open-graph-meta.tsx index 39495f973f..06a9729036 100644 --- a/packages/meta-tags/src/facebook-open-graph-meta.tsx +++ b/packages/meta-tags/src/pages-router/facebook-open-graph-meta.tsx @@ -1,7 +1,7 @@ import Head from 'next/head' import { useEnv } from '@titicaca/triple-web' -import { DEFAULT_OG_IMAGE } from './constants' +import { DEFAULT_OG_IMAGE } from '../constants' export function FacebookOpenGraphMeta({ title: titleFromProps, diff --git a/packages/meta-tags/src/pages-router/index.ts b/packages/meta-tags/src/pages-router/index.ts new file mode 100644 index 0000000000..51a57ad5da --- /dev/null +++ b/packages/meta-tags/src/pages-router/index.ts @@ -0,0 +1,6 @@ +export { EssentialContentMeta } from './essential-content-meta' +export { CommonMeta } from './common-meta' +export { AppleSmartBannerMeta } from './apple-smart-banner-meta' +export { FacebookAppLinkMeta } from './facebook-app-link-meta' +export { FacebookOpenGraphMeta } from './facebook-open-graph-meta' +export { ThemeColorMeta } from './theme-color-meta' diff --git a/packages/meta-tags/src/theme-color-meta.tsx b/packages/meta-tags/src/pages-router/theme-color-meta.tsx similarity index 80% rename from packages/meta-tags/src/theme-color-meta.tsx rename to packages/meta-tags/src/pages-router/theme-color-meta.tsx index 6e2a27bded..cbe5adce36 100644 --- a/packages/meta-tags/src/theme-color-meta.tsx +++ b/packages/meta-tags/src/pages-router/theme-color-meta.tsx @@ -1,7 +1,7 @@ import Head from 'next/head' -import { ThemeColor } from './types' -import { DEFAULT_THEME_COLOR } from './constants' +import { ThemeColor } from '../types' +import { DEFAULT_THEME_COLOR } from '../constants' export function ThemeColorMeta({ content = DEFAULT_THEME_COLOR, diff --git a/packages/meta-tags/src/product-script.tsx b/packages/meta-tags/src/product-script.tsx deleted file mode 100644 index 4e2aeead12..0000000000 --- a/packages/meta-tags/src/product-script.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import Head from 'next/head' - -import { createScript } from './utils' -import { ProductScriptProps } from './types' - -export function ProductScript(props: ProductScriptProps) { - const productScript = createScript(props, 'Product') - - return ( - - - - ) -} diff --git a/packages/meta-tags/src/review-script.tsx b/packages/meta-tags/src/review-script.tsx deleted file mode 100644 index e371dc1cce..0000000000 --- a/packages/meta-tags/src/review-script.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import Head from 'next/head' - -import { createScript } from './utils' -import { ReviewScriptProps } from './types' - -export function ReviewScript({ reviews }: ReviewScriptProps) { - const reviewScript = reviews.map((review) => createScript(review, 'Review')) - - return ( - - - - ) -} diff --git a/packages/meta-tags/src/structured-data/article-script.tsx b/packages/meta-tags/src/structured-data/article-script.tsx new file mode 100644 index 0000000000..c966b75161 --- /dev/null +++ b/packages/meta-tags/src/structured-data/article-script.tsx @@ -0,0 +1,18 @@ +import Script from 'next/script' + +import { createScript } from '../utils' +import { ArticleScriptProps } from '../types' + +export function ArticleScript(props: ArticleScriptProps) { + const articleScript = createScript(props, 'Article') + + return ( + + ) +} diff --git a/packages/meta-tags/src/structured-data/breadcrumb-list-script.tsx b/packages/meta-tags/src/structured-data/breadcrumb-list-script.tsx new file mode 100644 index 0000000000..d70f055f5a --- /dev/null +++ b/packages/meta-tags/src/structured-data/breadcrumb-list-script.tsx @@ -0,0 +1,18 @@ +import Script from 'next/script' + +import { createScript } from '../utils' +import { BreadcrumbListScriptProps } from '../types' + +export function BreadcrumbListScript(props: BreadcrumbListScriptProps) { + const breadcrumbScript = createScript(props, 'BreadcrumbList') + + return ( + + ) +} diff --git a/packages/meta-tags/src/structured-data/discussion-forum-posting-script.tsx b/packages/meta-tags/src/structured-data/discussion-forum-posting-script.tsx new file mode 100644 index 0000000000..83f99d6a49 --- /dev/null +++ b/packages/meta-tags/src/structured-data/discussion-forum-posting-script.tsx @@ -0,0 +1,20 @@ +import Script from 'next/script' + +import { createScript } from '../utils' +import { DiscussionForumPostingScriptProps } from '../types' + +export function DiscussionForumPostingScript( + props: DiscussionForumPostingScriptProps, +) { + const discussionForumPosting = createScript(props, 'DiscussionForumPosting') + + return ( + + ) +} diff --git a/packages/meta-tags/src/structured-data/index.ts b/packages/meta-tags/src/structured-data/index.ts new file mode 100644 index 0000000000..89862d6681 --- /dev/null +++ b/packages/meta-tags/src/structured-data/index.ts @@ -0,0 +1,7 @@ +export { ArticleScript } from './article-script' +export { BreadcrumbListScript } from './breadcrumb-list-script' +export { ProductScript } from './product-script' +export { LocalBusinessScript } from './local-business-script' +export { ReviewScript } from './review-script' +export { QaPageScript } from './qa-page-script' +export { DiscussionForumPostingScript } from './discussion-forum-posting-script' diff --git a/packages/meta-tags/src/structured-data/local-business-script.tsx b/packages/meta-tags/src/structured-data/local-business-script.tsx new file mode 100644 index 0000000000..8b6677f7bf --- /dev/null +++ b/packages/meta-tags/src/structured-data/local-business-script.tsx @@ -0,0 +1,21 @@ +import Script from 'next/script' + +import { SCHEMA_SCRIPT_TYPE_MAP, createScript } from '../utils' +import { LocalBusinessScriptProps } from '../types' + +export function LocalBusinessScript({ + type, + ...props +}: LocalBusinessScriptProps) { + const localBusinessScript = createScript(props, SCHEMA_SCRIPT_TYPE_MAP[type]) + + return ( + + ) +} diff --git a/packages/meta-tags/src/structured-data/product-script.tsx b/packages/meta-tags/src/structured-data/product-script.tsx new file mode 100644 index 0000000000..9326aab098 --- /dev/null +++ b/packages/meta-tags/src/structured-data/product-script.tsx @@ -0,0 +1,18 @@ +import Script from 'next/script' + +import { createScript } from '../utils' +import { ProductScriptProps } from '../types' + +export function ProductScript(props: ProductScriptProps) { + const productScript = createScript(props, 'Product') + + return ( + + ) +} diff --git a/packages/meta-tags/src/structured-data/qa-page-script.tsx b/packages/meta-tags/src/structured-data/qa-page-script.tsx new file mode 100644 index 0000000000..701b61c49e --- /dev/null +++ b/packages/meta-tags/src/structured-data/qa-page-script.tsx @@ -0,0 +1,18 @@ +import Script from 'next/script' + +import { createScript } from '../utils' +import { QaPageScriptProps } from '../types' + +export function QaPageScript(props: QaPageScriptProps) { + const qaPageScript = createScript(props, 'QAPage') + + return ( + + ) +} diff --git a/packages/meta-tags/src/structured-data/review-script.tsx b/packages/meta-tags/src/structured-data/review-script.tsx new file mode 100644 index 0000000000..0e2541109f --- /dev/null +++ b/packages/meta-tags/src/structured-data/review-script.tsx @@ -0,0 +1,18 @@ +import Script from 'next/script' + +import { createScript } from '../utils' +import { ReviewScriptProps } from '../types' + +export function ReviewScript({ reviews }: ReviewScriptProps) { + const reviewScript = reviews.map((review) => createScript(review, 'Review')) + + return ( + + ) +} diff --git a/packages/meta-tags/src/types/schema.ts b/packages/meta-tags/src/types/schema.ts index aa20d65c23..fa24ea1228 100644 --- a/packages/meta-tags/src/types/schema.ts +++ b/packages/meta-tags/src/types/schema.ts @@ -82,3 +82,29 @@ type RGBA = `rgba(${number}, ${number}, ${number}, ${number})` type HEX = `#${string}` export type ThemeColor = RGB | RGBA | HEX | Global + +export type InteractionStatisticType = 'LikeAction' | 'CommentAction' + +export interface InteractionStatistic { + interactionType: { + type: InteractionStatisticType + } + userInteractionCount: number +} + +export interface CommentType { + text: string + author: Author + datePublished: string + interactionStatistic?: InteractionStatistic[] + comment?: CommentType[] +} + +export interface Answer { + text: string + upvoteCount: number + url: string + datePublished: string + author: Author + comment?: CommentType[] +} diff --git a/packages/meta-tags/src/types/structured-data-script-props.ts b/packages/meta-tags/src/types/structured-data-script-props.ts index 593796aea9..e8bf2ac2c2 100644 --- a/packages/meta-tags/src/types/structured-data-script-props.ts +++ b/packages/meta-tags/src/types/structured-data-script-props.ts @@ -4,8 +4,11 @@ import { AddressSchema, AggregateOfferSchema, AggregateRatingSchema, + Answer, Author, + CommentType, GeoSchema, + InteractionStatistic, ListItem, OpeningHoursSpecificationSchema, ReviewSchema, @@ -53,3 +56,28 @@ export interface ProductScriptProps { export interface ReviewScriptProps { reviews: ReviewSchema[] } + +export interface DiscussionForumPostingScriptProps { + headline: string + text: string + url: string + author: Author + image?: string[] + datePublished: string + interactionStatistic: InteractionStatistic[] + comment: CommentType[] +} + +export interface QaPageScriptProps { + mainEntity: { + type: 'Question' + name: string + text: string + answerCount: number + upvoteCount: number + datePublished: string + author: Author + suggestedAnswer: Answer[] + acceptedAnswer?: Answer + } +} diff --git a/packages/meta-tags/src/utils.ts b/packages/meta-tags/src/utils.ts index 89ed479cd8..125f439922 100644 --- a/packages/meta-tags/src/utils.ts +++ b/packages/meta-tags/src/utils.ts @@ -17,6 +17,9 @@ const SCHEMA_TYPE_MAP: Record