diff --git a/blog.config.js b/blog.config.js index 37c12af0..e098b278 100644 --- a/blog.config.js +++ b/blog.config.js @@ -98,6 +98,351 @@ const BLOG = { GREETING_WORDS: process.env.NEXT_PUBLIC_GREETING_WORDS || 'Hi,我是一个程序员, Hi,我是一个打工人,Hi,我是一个干饭人,欢迎来到我的博客🎉' + ALGOLIA_APP_ID: process.env.NEXT_PUBLIC_ALGOLIA_APP_ID || null, // 在这里查看 https://dashboard.algolia.com/account/api-keys/ + ALGOLIA_ADMIN_APP_KEY: process.env.ALGOLIA_ADMIN_APP_KEY || null, // 管理后台的KEY,不要暴露在代码中,在这里查看 https://dashboard.algolia.com/account/api-keys/ + ALGOLIA_SEARCH_ONLY_APP_KEY: + process.env.NEXT_PUBLIC_ALGOLIA_SEARCH_ONLY_APP_KEY || null, // 客户端搜索用的KEY + ALGOLIA_INDEX: process.env.NEXT_PUBLIC_ALGOLIA_INDEX || null, // 在Algolia中创建一个index用作数据库 + // ALGOLIA_RECREATE_DATA: process.env.ALGOLIA_RECREATE_DATA || process.env.npm_lifecycle_event === 'build', // 为true时重新构建索引数据; 默认在build时会构建 + + PREVIEW_CATEGORY_COUNT: 16, // 首页最多展示的分类数量,0为不限制 + PREVIEW_TAG_COUNT: 16, // 首页最多展示的标签数量,0为不限制 + + POST_TITLE_ICON: process.env.NEXT_PUBLIC_POST_TITLE_ICON || true, // 是否显示标题icon + POST_DISABLE_GALLERY_CLICK: + process.env.NEXT_PUBLIC_POST_DISABLE_GALLERY_CLICK || false, // 画册视图禁止点击,方便在友链页面的画册插入链接 + + // ********动态特效相关******** + // 鼠标点击烟花特效 + FIREWORKS: process.env.NEXT_PUBLIC_FIREWORKS || false, // 开关 + // 烟花色彩,感谢 https://github.com/Vixcity 提交的色彩 + FIREWORKS_COLOR: [ + '255, 20, 97', + '24, 255, 146', + '90, 135, 255', + '251, 243, 140' + ], + + // 鼠标跟随特效 + MOUSE_FOLLOW: process.env.NEXT_PUBLIC_MOUSE_FOLLOW || false, // 开关 + // 这两个只有在鼠标跟随特效开启时才生效 + // 鼠标类型 1:路劲散点 2:下降散点 3:上升散点 4:边缘向鼠标移动散点 5:跟踪转圈散点 6:路径线条 7:聚集散点 8:聚集网格 9:移动网格 10:上升粒子 11:转圈随机颜色粒子 12:圆锥放射跟随蓝色粒子 + MOUSE_FOLLOW_EFFECT_TYPE: 11, // 1-12 + MOUSE_FOLLOW_EFFECT_COLOR: '#ef672a', // 鼠标点击特效颜色 #xxxxxx 或者 rgba(r,g,b,a) + + // 樱花飘落特效 + SAKURA: process.env.NEXT_PUBLIC_SAKURA || false, // 开关 + // 漂浮线段特效 + NEST: process.env.NEXT_PUBLIC_NEST || false, // 开关 + // 动态彩带特效 + FLUTTERINGRIBBON: process.env.NEXT_PUBLIC_FLUTTERINGRIBBON || false, // 开关 + // 静态彩带特效 + RIBBON: process.env.NEXT_PUBLIC_RIBBON || false, // 开关 + // 星空雨特效 黑夜模式才会生效 + STARRY_SKY: process.env.NEXT_PUBLIC_STARRY_SKY || false, // 开关 + + // AI 文章摘要生成 + AI_SUMMARY_API: process.env.AI_SUMMARY_API || '', + AI_SUMMARY_KEY: process.env.AI_SUMMARY_KEY || '', + AI_SUMMARY_CACHE_TIME: process.env.AI_SUMMARY_CACHE_TIME || 1800, // 缓存时间,单位秒 + AI_SUMMARY_WORD_LIMIT: process.env.AI_SUMMARY_WORD_LIMIT || 1000, + + // ********挂件组件相关******** + // AI 文章摘要生成 @see https://docs_s.tianli0.top/ + TianliGPT_CSS: + process.env.NEXT_PUBLIC_TIANLI_GPT_CSS || + 'https://cdn1.tianli0.top/gh/zhheo/Post-Abstract-AI@0.15.2/tianli_gpt.css', + TianliGPT_JS: + process.env.NEXT_PUBLIC_TIANLI_GPT_JS || + 'https://cdn1.tianli0.top/gh/zhheo/Post-Abstract-AI@0.15.2/tianli_gpt.js', + TianliGPT_KEY: process.env.NEXT_PUBLIC_TIANLI_GPT_KEY || '', + + // Chatbase 是否显示chatbase机器人 https://www.chatbase.co/ + CHATBASE_ID: process.env.NEXT_PUBLIC_CHATBASE_ID || null, + // WebwhizAI 机器人 @see https://github.com/webwhiz-ai/webwhiz + WEB_WHIZ_ENABLED: process.env.NEXT_PUBLIC_WEB_WHIZ_ENABLED || false, // 是否显示 + WEB_WHIZ_BASE_URL: + process.env.NEXT_PUBLIC_WEB_WHIZ_BASE_URL || 'https://api.webwhiz.ai', // 可以自建服务器 + WEB_WHIZ_CHAT_BOT_ID: process.env.NEXT_PUBLIC_WEB_WHIZ_CHAT_BOT_ID || null, // 在后台获取ID + DIFY_CHATBOT_ENABLED: process.env.NEXT_PUBLIC_DIFY_CHATBOT_ENABLED || false, + DIFY_CHATBOT_BASE_URL: process.env.NEXT_PUBLIC_DIFY_CHATBOT_BASE_URL || '', + DIFY_CHATBOT_TOKEN: process.env.NEXT_PUBLIC_DIFY_CHATBOT_TOKEN || '', + // 悬浮挂件 + WIDGET_PET: process.env.NEXT_PUBLIC_WIDGET_PET || true, // 是否显示宠物挂件 + WIDGET_PET_LINK: + process.env.NEXT_PUBLIC_WIDGET_PET_LINK || + 'https://cdn.jsdelivr.net/npm/live2d-widget-model-wanko@1.0.5/assets/wanko.model.json', // 挂件模型地址 @see https://github.com/xiazeyu/live2d-widget-models + WIDGET_PET_SWITCH_THEME: + process.env.NEXT_PUBLIC_WIDGET_PET_SWITCH_THEME || true, // 点击宠物挂件切换博客主题 + + SPOILER_TEXT_TAG: process.env.NEXT_PUBLIC_SPOILER_TEXT_TAG || '', // Spoiler文本隐藏功能,如Notion中 [sp]希望被spoiler的文字[sp],填入[sp] 即可 + + // 音乐播放插件 + MUSIC_PLAYER: process.env.NEXT_PUBLIC_MUSIC_PLAYER || false, // 是否使用音乐播放插件 + MUSIC_PLAYER_VISIBLE: process.env.NEXT_PUBLIC_MUSIC_PLAYER_VISIBLE || true, // 是否在左下角显示播放和切换,如果使用播放器,打开自动播放再隐藏,就会以类似背景音乐的方式播放,无法取消和暂停 + MUSIC_PLAYER_AUTO_PLAY: + process.env.NEXT_PUBLIC_MUSIC_PLAYER_AUTO_PLAY || true, // 是否自动播放,不过自动播放时常不生效(移动设备不支持自动播放) + MUSIC_PLAYER_LRC_TYPE: process.env.NEXT_PUBLIC_MUSIC_PLAYER_LRC_TYPE || '0', // 歌词显示类型,可选值: 3 | 1 | 0(0:禁用 lrc 歌词,1:lrc 格式的字符串,3:lrc 文件 url)(前提是有配置歌词路径,对 meting 无效) + MUSIC_PLAYER_CDN_URL: + process.env.NEXT_PUBLIC_MUSIC_PLAYER_CDN_URL || + 'https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/aplayer/1.10.1/APlayer.min.js', + MUSIC_PLAYER_ORDER: process.env.NEXT_PUBLIC_MUSIC_PLAYER_ORDER || 'list', // 默认播放方式,顺序 list,随机 random + MUSIC_PLAYER_AUDIO_LIST: [ + // 示例音乐列表。除了以下配置外,还可配置歌词,具体配置项看此文档 https://aplayer.js.org/#/zh-Hans/ + { + name: '风を共に舞う気持ち', + artist: 'Falcom Sound Team jdk', + url: 'https://music.163.com/song/media/outer/url?id=731419.mp3', + cover: + 'https://p2.music.126.net/kn6ugISTonvqJh3LHLaPtQ==/599233837187278.jpg' + }, + { + name: '王都グランセル', + artist: 'Falcom Sound Team jdk', + url: 'https://music.163.com/song/media/outer/url?id=731355.mp3', + cover: + 'https://p1.music.126.net/kn6ugISTonvqJh3LHLaPtQ==/599233837187278.jpg' + } + ], + MUSIC_PLAYER_METING: process.env.NEXT_PUBLIC_MUSIC_PLAYER_METING || false, // 是否要开启 MetingJS,从平台获取歌单。会覆盖自定义的 MUSIC_PLAYER_AUDIO_LIST,更多配置信息:https://github.com/metowolf/MetingJS + MUSIC_PLAYER_METING_SERVER: + process.env.NEXT_PUBLIC_MUSIC_PLAYER_METING_SERVER || 'netease', // 音乐平台,[netease, tencent, kugou, xiami, baidu] + MUSIC_PLAYER_METING_ID: + process.env.NEXT_PUBLIC_MUSIC_PLAYER_METING_ID || '60198', // 对应歌单的 id + MUSIC_PLAYER_METING_LRC_TYPE: + process.env.NEXT_PUBLIC_MUSIC_PLAYER_METING_LRC_TYPE || '1', // 已废弃!!!可选值: 3 | 1 | 0(0:禁用 lrc 歌词,1:lrc 格式的字符串,3:lrc 文件 url) + + // ********挂件组件相关******** + // ----> 评论互动 可同时开启多个支持 WALINE VALINE GISCUS CUSDIS UTTERRANCES GITALK + + COMMENT_HIDE_SINGLE_TAB: + process.env.NEXT_PUBLIC_COMMENT_HIDE_SINGLE_TAB || false, // Whether hide the tab when there's no tabs. 只有一个评论组件时是否隐藏切换组件的标签页 + + // artalk 评论插件 + COMMENT_ARTALK_SERVER: process.env.NEXT_PUBLIC_COMMENT_ARTALK_SERVER || '', // ArtalkServert后端地址 https://artalk.js.org/guide/deploy.html + COMMENT_ARTALK_JS: + process.env.NEXT_PUBLIC_COMMENT_ARTALK_JS || + 'https://cdnjs.cloudflare.com/ajax/libs/artalk/2.5.5/Artalk.js', // ArtalkServert js cdn + COMMENT_ARTALK_CSS: + process.env.NEXT_PUBLIC_COMMENT_ARTALK_CSS || + 'https://cdnjs.cloudflare.com/ajax/libs/artalk/2.5.5/Artalk.css', // ArtalkServert css cdn + + // twikoo + COMMENT_TWIKOO_ENV_ID: process.env.NEXT_PUBLIC_COMMENT_ENV_ID || '', // TWIKOO后端地址 腾讯云环境填envId;Vercel环境填域名,教程:https://tangly1024.com/article/notionnext-twikoo + COMMENT_TWIKOO_COUNT_ENABLE: + process.env.NEXT_PUBLIC_COMMENT_TWIKOO_COUNT_ENABLE || false, // 博客列表是否显示评论数 + COMMENT_TWIKOO_CDN_URL: + process.env.NEXT_PUBLIC_COMMENT_TWIKOO_CDN_URL || + 'https://cdn.jsdelivr.net/npm/twikoo@1.6.17/dist/twikoo.all.min.js', // twikoo客户端cdn + + // utterance + COMMENT_UTTERRANCES_REPO: + process.env.NEXT_PUBLIC_COMMENT_UTTERRANCES_REPO || '', // 你的代码仓库名, 例如我是 'tangly1024/NotionNext'; 更多文档参考 https://utteranc.es/ + + // giscus @see https://giscus.app/ + COMMENT_GISCUS_REPO: process.env.NEXT_PUBLIC_COMMENT_GISCUS_REPO || '', // 你的Github仓库名 e.g 'tangly1024/NotionNext' + COMMENT_GISCUS_REPO_ID: process.env.NEXT_PUBLIC_COMMENT_GISCUS_REPO_ID || '', // 你的Github Repo ID e.g ( 設定完 giscus 即可看到 ) + COMMENT_GISCUS_CATEGORY_ID: + process.env.NEXT_PUBLIC_COMMENT_GISCUS_CATEGORY_ID || '', // 你的Github Discussions 內的 Category ID ( 設定完 giscus 即可看到 ) + COMMENT_GISCUS_MAPPING: + process.env.NEXT_PUBLIC_COMMENT_GISCUS_MAPPING || 'pathname', // 你的Github Discussions 使用哪種方式來標定文章, 預設 'pathname' + COMMENT_GISCUS_REACTIONS_ENABLED: + process.env.NEXT_PUBLIC_COMMENT_GISCUS_REACTIONS_ENABLED || '1', // 你的 Giscus 是否開啟文章表情符號 '1' 開啟 "0" 關閉 預設開啟 + COMMENT_GISCUS_EMIT_METADATA: + process.env.NEXT_PUBLIC_COMMENT_GISCUS_EMIT_METADATA || '0', // 你的 Giscus 是否提取 Metadata '1' 開啟 '0' 關閉 預設關閉 + COMMENT_GISCUS_INPUT_POSITION: + process.env.NEXT_PUBLIC_COMMENT_GISCUS_INPUT_POSITION || 'bottom', // 你的 Giscus 發表留言位置 'bottom' 尾部 'top' 頂部, 預設 'bottom' + COMMENT_GISCUS_LANG: process.env.NEXT_PUBLIC_COMMENT_GISCUS_LANG || 'zh-CN', // 你的 Giscus 語言 e.g 'en', 'zh-TW', 'zh-CN', 預設 'en' + COMMENT_GISCUS_LOADING: + process.env.NEXT_PUBLIC_COMMENT_GISCUS_LOADING || 'lazy', // 你的 Giscus 載入是否漸進式載入, 預設 'lazy' + COMMENT_GISCUS_CROSSORIGIN: + process.env.NEXT_PUBLIC_COMMENT_GISCUS_CROSSORIGIN || 'anonymous', // 你的 Giscus 可以跨網域, 預設 'anonymous' + + COMMENT_CUSDIS_APP_ID: process.env.NEXT_PUBLIC_COMMENT_CUSDIS_APP_ID || '', // data-app-id 36位 see https://cusdis.com/ + COMMENT_CUSDIS_HOST: + process.env.NEXT_PUBLIC_COMMENT_CUSDIS_HOST || 'https://cusdis.com', // data-host, change this if you're using self-hosted version + COMMENT_CUSDIS_SCRIPT_SRC: + process.env.NEXT_PUBLIC_COMMENT_CUSDIS_SCRIPT_SRC || '/js/cusdis.es.js', // change this if you're using self-hosted version + + // gitalk评论插件 更多参考 https://gitalk.github.io/ + COMMENT_GITALK_REPO: process.env.NEXT_PUBLIC_COMMENT_GITALK_REPO || '', // 你的Github仓库名,例如 'NotionNext' + COMMENT_GITALK_OWNER: process.env.NEXT_PUBLIC_COMMENT_GITALK_OWNER || '', // 你的用户名 e.g tangly1024 + COMMENT_GITALK_ADMIN: process.env.NEXT_PUBLIC_COMMENT_GITALK_ADMIN || '', // 管理员用户名、一般是自己 e.g 'tangly1024' + COMMENT_GITALK_CLIENT_ID: + process.env.NEXT_PUBLIC_COMMENT_GITALK_CLIENT_ID || '', // e.g 20位ID , 在gitalk后台获取 + COMMENT_GITALK_CLIENT_SECRET: + process.env.NEXT_PUBLIC_COMMENT_GITALK_CLIENT_SECRET || '', // e.g 40位ID, 在gitalk后台获取 + COMMENT_GITALK_DISTRACTION_FREE_MODE: false, // 类似facebook的无干扰模式 + COMMENT_GITALK_JS_CDN_URL: + process.env.NEXT_PUBLIC_COMMENT_GITALK_JS_CDN_URL || + 'https://cdn.jsdelivr.net/npm/gitalk@1/dist/gitalk.min.js', // gitalk客户端 js cdn + COMMENT_GITALK_CSS_CDN_URL: + process.env.NEXT_PUBLIC_COMMENT_GITALK_CSS_CDN_URL || + 'https://cdn.jsdelivr.net/npm/gitalk@1/dist/gitalk.css', // gitalk客户端 css cdn + + COMMENT_GITTER_ROOM: process.env.NEXT_PUBLIC_COMMENT_GITTER_ROOM || '', // gitter聊天室 see https://gitter.im/ 不需要则留空 + COMMENT_DAO_VOICE_ID: process.env.NEXT_PUBLIC_COMMENT_DAO_VOICE_ID || '', // DaoVoice http://dashboard.daovoice.io/get-started + COMMENT_TIDIO_ID: process.env.NEXT_PUBLIC_COMMENT_TIDIO_ID || '', // [tidio_id] -> //code.tidio.co/[tidio_id].js + + COMMENT_VALINE_CDN: + process.env.NEXT_PUBLIC_VALINE_CDN || + 'https://unpkg.com/valine@1.5.1/dist/Valine.min.js', + COMMENT_VALINE_APP_ID: process.env.NEXT_PUBLIC_VALINE_ID || '', // Valine @see https://valine.js.org/quickstart.html 或 https://github.com/stonehank/react-valine#%E8%8E%B7%E5%8F%96app-id-%E5%92%8C-app-key + COMMENT_VALINE_APP_KEY: process.env.NEXT_PUBLIC_VALINE_KEY || '', + COMMENT_VALINE_SERVER_URLS: process.env.NEXT_PUBLIC_VALINE_SERVER_URLS || '', // 该配置适用于国内自定义域名用户, 海外版本会自动检测(无需手动填写) @see https://valine.js.org/configuration.html#serverURLs + COMMENT_VALINE_PLACEHOLDER: + process.env.NEXT_PUBLIC_VALINE_PLACEHOLDER || '抢个沙发吧~', // 可以搭配后台管理评论 https://github.com/DesertsP/Valine-Admin 便于查看评论,以及邮件通知,垃圾评论过滤等功能 + + COMMENT_WALINE_SERVER_URL: process.env.NEXT_PUBLIC_WALINE_SERVER_URL || '', // 请配置完整的Waline评论地址 例如 hhttps://preview-waline.tangly1024.com @see https://waline.js.org/guide/get-started.html + COMMENT_WALINE_RECENT: process.env.NEXT_PUBLIC_WALINE_RECENT || false, // 最新评论 + + // 此评论系统基于WebMention,细节可参考https://webmention.io + // 它是一个基于IndieWeb理念的开放式评论系统,下方COMMENT_WEBMENTION包含的属性皆需配置: + // ENABLE: 是否开启 + // AUTH: Webmention使用的IndieLogin,可使用Twitter或Github个人页面连结 + // HOSTNAME: Webmention绑定之网域,通常即为本站网址 + // TWITTER_USERNAME: 评论显示区域需要的资讯 + // TOKEN: Webmention的API token + COMMENT_WEBMENTION_ENABLE: process.env.NEXT_PUBLIC_WEBMENTION_ENABLE || false, + COMMENT_WEBMENTION_AUTH: process.env.NEXT_PUBLIC_WEBMENTION_AUTH || '', + COMMENT_WEBMENTION_HOSTNAME: + process.env.NEXT_PUBLIC_WEBMENTION_HOSTNAME || '', + COMMENT_WEBMENTION_TWITTER_USERNAME: + process.env.NEXT_PUBLIC_TWITTER_USERNAME || '', + COMMENT_WEBMENTION_TOKEN: process.env.NEXT_PUBLIC_WEBMENTION_TOKEN || '', + + // <---- 评论插件 + + // ----> 站点统计 + ANALYTICS_VERCEL: process.env.NEXT_PUBLIC_ANALYTICS_VERCEL || false, // vercel自带的统计 https://vercel.com/docs/concepts/analytics/quickstart https://github.com/tangly1024/NotionNext/issues/897 + ANALYTICS_BUSUANZI_ENABLE: + process.env.NEXT_PUBLIC_ANALYTICS_BUSUANZI_ENABLE || true, // 展示网站阅读量、访问数 see http://busuanzi.ibruce.info/ + ANALYTICS_BAIDU_ID: process.env.NEXT_PUBLIC_ANALYTICS_BAIDU_ID || '', // e.g 只需要填写百度统计的id,[baidu_id] -> https://hm.baidu.com/hm.js?[baidu_id] + ANALYTICS_CNZZ_ID: process.env.NEXT_PUBLIC_ANALYTICS_CNZZ_ID || '', // 只需要填写站长统计的id, [cnzz_id] -> https://s9.cnzz.com/z_stat.php?id=[cnzz_id]&web_id=[cnzz_id] + ANALYTICS_GOOGLE_ID: process.env.NEXT_PUBLIC_ANALYTICS_GOOGLE_ID || '', // 谷歌Analytics的id e.g: G-XXXXXXXXXX + + // 51la 站点统计 https://www.51.la/ + ANALYTICS_51LA_ID: process.env.NEXT_PUBLIC_ANALYTICS_51LA_ID || '', // id,在51la后台获取 参阅 https://docs.tangly1024.com/article/notion-next-51-la + ANALYTICS_51LA_CK: process.env.NEXT_PUBLIC_ANALYTICS_51LA_CK || '', // ck,在51la后台获取 + + // Matomo 网站统计 + MATOMO_HOST_URL: process.env.NEXT_PUBLIC_MATOMO_HOST_URL || '', // Matomo服务器地址,不带斜杠 + MATOMO_SITE_ID: process.env.NEXT_PUBLIC_MATOMO_SITE_ID || '', // Matomo网站ID + // ACKEE网站访客统计工具 + ANALYTICS_ACKEE_TRACKER: + process.env.NEXT_PUBLIC_ANALYTICS_ACKEE_TRACKER || '', // e.g 'https://ackee.tangly1024.com/tracker.js' + ANALYTICS_ACKEE_DATA_SERVER: + process.env.NEXT_PUBLIC_ANALYTICS_ACKEE_DATA_SERVER || '', // e.g https://ackee.tangly1024.com , don't end with a slash + ANALYTICS_ACKEE_DOMAIN_ID: + process.env.NEXT_PUBLIC_ANALYTICS_ACKEE_DOMAIN_ID || '', // e.g '82e51db6-dec2-423a-b7c9-b4ff7ebb3302' + + SEO_GOOGLE_SITE_VERIFICATION: + process.env.NEXT_PUBLIC_SEO_GOOGLE_SITE_VERIFICATION || '', // Remove the value or replace it with your own google site verification code + + SEO_BAIDU_SITE_VERIFICATION: + process.env.NEXT_PUBLIC_SEO_BAIDU_SITE_VERIFICATION || '', // Remove the value or replace it with your own google site verification code + + // 微软 Clarity 站点分析 + CLARITY_ID: process.env.NEXT_PUBLIC_CLARITY_ID || null, // 只需要复制Clarity脚本中的ID部分,ID是一个十位的英文数字组合 + + // <---- 站点统计 + + // START---->营收相关 + + // 谷歌广告 + ADSENSE_GOOGLE_ID: process.env.NEXT_PUBLIC_ADSENSE_GOOGLE_ID || '', // 谷歌广告ID e.g ca-pub-xxxxxxxxxxxxxxxx + ADSENSE_GOOGLE_TEST: process.env.NEXT_PUBLIC_ADSENSE_GOOGLE_TEST || false, // 谷歌广告ID测试模式,这种模式获取假的测试广告,用于开发 https://www.tangly1024.com/article/local-dev-google-adsense + ADSENSE_GOOGLE_SLOT_IN_ARTICLE: + process.env.NEXT_PUBLIC_ADSENSE_GOOGLE_SLOT_IN_ARTICLE || '3806269138', // Google AdScene>广告>按单元广告>新建文章内嵌广告 粘贴html代码中的data-ad-slot值 + ADSENSE_GOOGLE_SLOT_FLOW: + process.env.NEXT_PUBLIC_ADSENSE_GOOGLE_SLOT_FLOW || '1510444138', // Google AdScene>广告>按单元广告>新建信息流广告 + ADSENSE_GOOGLE_SLOT_NATIVE: + process.env.NEXT_PUBLIC_ADSENSE_GOOGLE_SLOT_NATIVE || '4980048999', // Google AdScene>广告>按单元广告>新建原生广告 + ADSENSE_GOOGLE_SLOT_AUTO: + process.env.NEXT_PUBLIC_ADSENSE_GOOGLE_SLOT_AUTO || '8807314373', // Google AdScene>广告>按单元广告>新建展示广告 (自动广告) + + // 万维广告 + AD_WWADS_ID: process.env.NEXT_PUBLIC_WWAD_ID || null, // https://wwads.cn/ 创建您的万维广告单元ID + AD_WWADS_BLOCK_DETECT: process.env.NEXT_PUBLIC_WWADS_AD_BLOCK_DETECT || false, // 是否开启WWADS广告屏蔽插件检测,开启后会在广告位上以文字提示 @see https://github.com/bytegravity/whitelist-wwads + + // END<----营收相关 + + // 自定义配置notion数据库字段名 + NOTION_PROPERTY_NAME: { + password: process.env.NEXT_PUBLIC_NOTION_PROPERTY_PASSWORD || 'password', + type: process.env.NEXT_PUBLIC_NOTION_PROPERTY_TYPE || 'type', // 文章类型, + type_post: process.env.NEXT_PUBLIC_NOTION_PROPERTY_TYPE_POST || 'Post', // 当type文章类型与此值相同时,为博文。 + type_page: process.env.NEXT_PUBLIC_NOTION_PROPERTY_TYPE_PAGE || 'Page', // 当type文章类型与此值相同时,为单页。 + type_notice: + process.env.NEXT_PUBLIC_NOTION_PROPERTY_TYPE_NOTICE || 'Notice', // 当type文章类型与此值相同时,为公告。 + type_menu: process.env.NEXT_PUBLIC_NOTION_PROPERTY_TYPE_MENU || 'Menu', // 当type文章类型与此值相同时,为菜单。 + type_sub_menu: + process.env.NEXT_PUBLIC_NOTION_PROPERTY_TYPE_SUB_MENU || 'SubMenu', // 当type文章类型与此值相同时,为子菜单。 + title: process.env.NEXT_PUBLIC_NOTION_PROPERTY_TITLE || 'title', // 文章标题 + status: process.env.NEXT_PUBLIC_NOTION_PROPERTY_STATUS || 'status', + status_publish: + process.env.NEXT_PUBLIC_NOTION_PROPERTY_STATUS_PUBLISH || 'Published', // 当status状态值与此相同时为发布,可以为中文 + status_invisible: + process.env.NEXT_PUBLIC_NOTION_PROPERTY_STATUS_INVISIBLE || 'Invisible', // 当status状态值与此相同时为隐藏发布,可以为中文 , 除此之外其他页面状态不会显示在博客上 + summary: process.env.NEXT_PUBLIC_NOTION_PROPERTY_SUMMARY || 'summary', + slug: process.env.NEXT_PUBLIC_NOTION_PROPERTY_SLUG || 'slug', + category: process.env.NEXT_PUBLIC_NOTION_PROPERTY_CATEGORY || 'category', + date: process.env.NEXT_PUBLIC_NOTION_PROPERTY_DATE || 'date', + tags: process.env.NEXT_PUBLIC_NOTION_PROPERTY_TAGS || 'tags', + icon: process.env.NEXT_PUBLIC_NOTION_PROPERTY_ICON || 'icon', + ext: process.env.NEXT_PUBLIC_NOTION_PROPERTY_EXT || 'ext' // 扩展字段,存放json-string,用于复杂业务 + }, + + // RSS订阅 + ENABLE_RSS: process.env.NEXT_PUBLIC_ENABLE_RSS || true, // 是否开启RSS订阅功能 + MAILCHIMP_LIST_ID: process.env.MAILCHIMP_LIST_ID || null, // 开启mailichimp邮件订阅 客户列表ID ,具体使用方法参阅文档 + MAILCHIMP_API_KEY: process.env.MAILCHIMP_API_KEY || null, // 开启mailichimp邮件订阅 APIkey + + // uuid重定向至 slug + UUID_REDIRECT: process.env.UUID_REDIRECT || false, + + // ANIMATE.css 动画 + ANIMATE_CSS_URL: + process.env.NEXT_PUBLIC_ANIMATE_CSS_URL || + 'https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css', // 动画CDN + + // 网站图片 + IMG_LAZY_LOAD_PLACEHOLDER: + process.env.NEXT_PUBLIC_IMG_LAZY_LOAD_PLACEHOLDER || + 'data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==', // 懒加载占位图片地址,支持base64或url + IMG_URL_TYPE: process.env.NEXT_PUBLIC_IMG_TYPE || 'Notion', // 此配置已失效,请勿使用;AMAZON方案不再支持,仅支持Notion方案。 ['Notion','AMAZON'] 站点图片前缀 默认 Notion:(https://notion.so/images/xx) , AMAZON(https://s3.us-west-2.amazonaws.com/xxx) + IMG_SHADOW: process.env.NEXT_PUBLIC_IMG_SHADOW || false, // 文章图片是否自动添加阴影 + IMG_COMPRESS_WIDTH: process.env.NEXT_PUBLIC_IMG_COMPRESS_WIDTH || 800, // Notion图片压缩宽度 + + // 作废配置 + AVATAR: process.env.NEXT_PUBLIC_AVATAR || '/avatar.svg', // 作者头像,被notion中的ICON覆盖。若无ICON则取public目录下的avatar.png + TITLE: process.env.NEXT_PUBLIC_TITLE || 'NotionNext BLOG', // 站点标题 ,被notion中的页面标题覆盖;此处请勿留空白,否则服务器无法编译 + HOME_BANNER_IMAGE: + process.env.NEXT_PUBLIC_HOME_BANNER_IMAGE || '/bg_image.jpg', // 首页背景大图, 会被notion中的封面图覆盖,若无封面图则会使用代码中的 /public/bg_image.jpg 文件 + DESCRIPTION: + process.env.NEXT_PUBLIC_DESCRIPTION || '这是一个由NotionNext生成的站点', // 站点描述,被notion中的页面描述覆盖 + + // 开发相关 + NOTION_ACTIVE_USER: process.env.NOTION_ACTIVE_USER || '', + NOTION_TOKEN_V2: process.env.NOTION_TOKEN_V2 || '', // Useful if you prefer not to make your database public + DEBUG: process.env.NEXT_PUBLIC_DEBUG || false, // 是否显示调试按钮 + ENABLE_CACHE: + process.env.ENABLE_CACHE || + process.env.npm_lifecycle_event === 'build' || + process.env.npm_lifecycle_event === 'export', // 在打包过程中默认开启缓存,开发或运行时开启此功能意义不大。 + isProd: process.env.VERCEL_ENV === 'production' || process.env.EXPORT, // distinguish between development and production environment (ref: https://vercel.com/docs/environment-variables#system-environment-variables) + BUNDLE_ANALYZER: process.env.ANALYZE === 'true' || false, // 是否展示编译依赖内容与大小 + VERSION: (() => { + try { + // 优先使用环境变量,否则从package.json中获取版本号 + return ( + process.env.NEXT_PUBLIC_VERSION || require('./package.json').version + ) + } catch (error) { + console.warn('Failed to load package.json version:', error) + return '1.0.0' // 缺省版本号 + } + })() } module.exports = BLOG diff --git a/lib/config.js b/lib/config.js index 314e8318..3712d877 100644 --- a/lib/config.js +++ b/lib/config.js @@ -42,6 +42,7 @@ export const siteConfig = (key, defaultVal = null, extendConfig = {}) => { case 'AI_SUMMARY_KEY': case 'AI_SUMMARY_CACHE_TIME': case 'AI_SUMMARY_WORD_LIMIT': + case 'UUID_REDIRECT': // LINK比较特殊, if (key === 'LINK') { if (!extendConfig || Object.keys(extendConfig).length === 0) { diff --git a/lib/redirect.js b/lib/redirect.js new file mode 100644 index 00000000..7a05dfee --- /dev/null +++ b/lib/redirect.js @@ -0,0 +1,15 @@ +import fs from 'fs' + +export function generateRedirectJson({ allPages }) { + let uuidSlugMap = {} + allPages.forEach(page => { + if (page.type === 'Post' && page.status === 'Published') { + uuidSlugMap[page.id] = page.slug + } + }) + try { + fs.writeFileSync('./public/redirect.json', JSON.stringify(uuidSlugMap)) + } catch (error) { + console.warn('无法写入文件', error) + } +} diff --git a/middleware.ts b/middleware.ts index dc623d08..550c6f8b 100644 --- a/middleware.ts +++ b/middleware.ts @@ -1,5 +1,8 @@ import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server' -import { NextResponse } from 'next/server' +import { NextRequest, NextResponse } from 'next/server' +import { checkStrIsNotionId, getLastPartOfUrl } from '@/lib/utils' +import { idToUuid } from 'notion-utils' +import BLOG from './blog.config' /** * Clerk 身份验证中间件 @@ -30,8 +33,31 @@ const isTenantAdminRoute = createRouteMatcher([ * @returns */ // eslint-disable-next-line @typescript-eslint/require-await, @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars -const noAuthMiddleware = async (req: any, ev: any) => { +const noAuthMiddleware = async (req: NextRequest, ev: any) => { // 如果没有配置 Clerk 相关环境变量,返回一个默认响应或者继续处理请求 + if (BLOG['UUID_REDIRECT']) { + let redirectJson: Record = {} + try { + const response = await fetch(`${req.nextUrl.origin}/redirect.json`) + if (response.ok) { + redirectJson = (await response.json()) as Record + } + } catch (err) { + console.error('Error fetching static file:', err) + } + let lastPart = getLastPartOfUrl(req.nextUrl.pathname) as string + if (checkStrIsNotionId(lastPart)) { + lastPart = idToUuid(lastPart) + } + if (lastPart && redirectJson[lastPart]) { + const redirectToUrl = req.nextUrl.clone() + redirectToUrl.pathname = '/' + redirectJson[lastPart] + console.log( + `redirect from ${req.nextUrl.pathname} to ${redirectToUrl.pathname}` + ) + return NextResponse.redirect(redirectToUrl, 308) + } + } return NextResponse.next() } /** diff --git a/pages/index.js b/pages/index.js index 31e2610b..b66b5610 100644 --- a/pages/index.js +++ b/pages/index.js @@ -5,6 +5,7 @@ import { generateRobotsTxt } from '@/lib/robots.txt' import { generateRss } from '@/lib/rss' import { generateSitemapXml } from '@/lib/sitemap.xml' import { DynamicLayout } from '@/themes/theme' +import { generateRedirectJson } from '@/lib/redirect' /** * 首页布局 @@ -60,6 +61,10 @@ export async function getStaticProps(req) { generateRss(props) // 生成 generateSitemapXml(props) + if (siteConfig('UUID_REDIRECT', false, props?.NOTION_CONFIG)) { + // 生成重定向 JSON + generateRedirectJson(props) + } // 生成全文索引 - 仅在 yarn build 时执行 && process.env.npm_lifecycle_event === 'build' diff --git a/themes/theme.js b/themes/theme.js index 97fcd64a..3d89f878 100644 --- a/themes/theme.js +++ b/themes/theme.js @@ -6,7 +6,7 @@ import { useRouter } from 'next/router' import { getQueryParam, getQueryVariable, isBrowser } from '../lib/utils' // 在next.config.js中扫描所有主题 -export const { THEMES = [] } = getConfig().publicRuntimeConfig +export const { THEMES = [] } = getConfig()?.publicRuntimeConfig || {} /** * 获取主题配置