import { siteConfig } from '@/lib/config' import { useGlobal } from '@/lib/global' import { loadExternalResource } from '@/lib/utils' import Head from 'next/head' import { useRouter } from 'next/router' import { useEffect } from 'react' /** * 页面的Head头,有用于SEO * @param {*} param0 * @returns */ const GlobalHead = props => { const { children, siteInfo, post, NOTION_CONFIG } = props let url = siteConfig('PATH')?.length ? `${siteConfig('LINK')}/${siteConfig('SUB_PATH', '')}` : siteConfig('LINK') let image const router = useRouter() const meta = getSEOMeta(props, router, useGlobal()?.locale) if (meta) { url = `${url}/${meta.slug}` image = meta.image || '/bg_image.jpg' } const title = meta?.title || siteConfig('TITLE') const description = meta?.description || `${siteInfo?.description}` const type = meta?.type || 'website' const lang = siteConfig('LANG').replace('-', '_') // Facebook OpenGraph 要 zh_CN 這樣的格式才抓得到語言 const category = meta?.category || siteConfig('KEYWORDS') // section 主要是像是 category 這樣的分類,Facebook 用這個來抓連結的分類 const favicon = siteConfig('BLOG_FAVICON') const webFontUrl = siteConfig('FONT_URL') const BACKGROUND_DARK = siteConfig('BACKGROUND_DARK', '', NOTION_CONFIG) const SEO_BAIDU_SITE_VERIFICATION = siteConfig( 'SEO_BAIDU_SITE_VERIFICATION', null, NOTION_CONFIG ) const SEO_GOOGLE_SITE_VERIFICATION = siteConfig( 'SEO_GOOGLE_SITE_VERIFICATION', null, NOTION_CONFIG ) const BLOG_FAVICON = siteConfig('BLOG_FAVICON', null, NOTION_CONFIG) const COMMENT_WEBMENTION_ENABLE = siteConfig( 'COMMENT_WEBMENTION_ENABLE', null, NOTION_CONFIG ) const COMMENT_WEBMENTION_HOSTNAME = siteConfig( 'COMMENT_WEBMENTION_HOSTNAME', null, NOTION_CONFIG ) const COMMENT_WEBMENTION_AUTH = siteConfig( 'COMMENT_WEBMENTION_AUTH', null, NOTION_CONFIG ) const ANALYTICS_BUSUANZI_ENABLE = siteConfig( 'ANALYTICS_BUSUANZI_ENABLE', null, NOTION_CONFIG ) const FACEBOOK_PAGE = siteConfig('FACEBOOK_PAGE', null, NOTION_CONFIG) // SEO关键词 let keywords = meta?.tags || siteConfig('KEYWORDS') if (post?.tags && post?.tags?.length > 0) { keywords = post?.tags?.join(',') } useEffect(() => { // 使用WebFontLoader字体加载 loadExternalResource( 'https://cdnjs.cloudflare.com/ajax/libs/webfont/1.6.28/webfontloader.js', 'js' ).then(url => { const WebFont = window?.WebFont if (WebFont) { console.log('LoadWebFont', webFontUrl) WebFont.load({ custom: { // families: ['"LXGW WenKai"'], urls: webFontUrl } }) } }) }, []) return ( {title} {SEO_GOOGLE_SITE_VERIFICATION && ( )} {SEO_BAIDU_SITE_VERIFICATION && ( )} {COMMENT_WEBMENTION_ENABLE && ( <> {COMMENT_WEBMENTION_AUTH && ( )} )} {ANALYTICS_BUSUANZI_ENABLE && ( )} {meta?.type === 'Post' && ( <> )} {children} ) } /** * 获取SEO信息 * @param {*} props * @param {*} router */ const getSEOMeta = (props, router, locale) => { const { post, siteInfo, tag, category, page } = props const keyword = router?.query?.s switch (router.route) { case '/': return { title: `${siteInfo?.title} | ${siteInfo?.description}`, description: `${siteInfo?.description}`, image: `${siteInfo?.pageCover}`, slug: '', type: 'website' } case '/archive': return { title: `${locale.NAV.ARCHIVE} | ${siteInfo?.title}`, description: `${siteInfo?.description}`, image: `${siteInfo?.pageCover}`, slug: 'archive', type: 'website' } case '/page/[page]': return { title: `${page} | Page | ${siteInfo?.title}`, description: `${siteInfo?.description}`, image: `${siteInfo?.pageCover}`, slug: 'page/' + page, type: 'website' } case '/category/[category]': return { title: `${category} | ${locale.COMMON.CATEGORY} | ${siteInfo?.title}`, description: `${siteInfo?.description}`, slug: 'category/' + category, image: `${siteInfo?.pageCover}`, type: 'website' } case '/category/[category]/page/[page]': return { title: `${category} | ${locale.COMMON.CATEGORY} | ${siteInfo?.title}`, description: `${siteInfo?.description}`, slug: 'category/' + category, image: `${siteInfo?.pageCover}`, type: 'website' } case '/tag/[tag]': case '/tag/[tag]/page/[page]': return { title: `${tag} | ${locale.COMMON.TAGS} | ${siteInfo?.title}`, description: `${siteInfo?.description}`, image: `${siteInfo?.pageCover}`, slug: 'tag/' + tag, type: 'website' } case '/search': return { title: `${keyword || ''}${keyword ? ' | ' : ''}${locale.NAV.SEARCH} | ${siteInfo?.title}`, description: `${siteInfo?.description}`, image: `${siteInfo?.pageCover}`, slug: 'search', type: 'website' } case '/search/[keyword]': case '/search/[keyword]/page/[page]': return { title: `${keyword || ''}${keyword ? ' | ' : ''}${locale.NAV.SEARCH} | ${siteInfo?.title}`, description: siteConfig('TITLE'), image: `${siteInfo?.pageCover}`, slug: 'search/' + (keyword || ''), type: 'website' } case '/404': return { title: `${siteInfo?.title} | 页面找不到啦`, image: `${siteInfo?.pageCover}` } case '/tag': return { title: `${locale.COMMON.TAGS} | ${siteInfo?.title}`, description: `${siteInfo?.description}`, image: `${siteInfo?.pageCover}`, slug: 'tag', type: 'website' } case '/category': return { title: `${locale.COMMON.CATEGORY} | ${siteInfo?.title}`, description: `${siteInfo?.description}`, image: `${siteInfo?.pageCover}`, slug: 'category', type: 'website' } default: return { title: post ? `${post?.title} | ${siteInfo?.title}` : `${siteInfo?.title} | loading`, description: post?.summary, type: post?.type, slug: post?.slug, image: post?.pageCoverThumbnail || `${siteInfo?.pageCover}`, category: post?.category?.[0], tags: post?.tags } } } export default GlobalHead