Skip to content
Open

11 #4215

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
ee1711c
Update blog.config.js
daheitian Jun 18, 2024
0c430cf
Update blog.config.js
daheitian Jun 18, 2024
d217a94
Update blog.config.js
daheitian Jun 18, 2024
5d685fa
Update blog.config.js
daheitian Jun 18, 2024
a067afa
Merge branch 'main' of https://github.com/tangly1024/NotionNext
actions-user Jun 20, 2024
e28dfa4
Merge branch 'main' of https://github.com/tangly1024/NotionNext
actions-user Jun 23, 2024
945d449
Merge branch 'main' of https://github.com/tangly1024/NotionNext
actions-user Jun 25, 2024
463d2a6
Merge branch 'main' of https://github.com/tangly1024/NotionNext
actions-user Jun 27, 2024
3670cc9
Merge branch 'main' of https://github.com/tangly1024/NotionNext
actions-user Jun 28, 2024
c0305eb
Merge branch 'main' of https://github.com/tangly1024/NotionNext
actions-user Jun 29, 2024
2083c12
Update blog.config.js
daheitian Jul 4, 2024
f260ea8
Merge branch 'main' of https://github.com/tangly1024/NotionNext
actions-user Jul 6, 2024
bdb24d5
Merge branch 'main' of https://github.com/tangly1024/NotionNext
actions-user Jul 8, 2024
fcabfbc
Merge branch 'main' of https://github.com/tangly1024/NotionNext
actions-user Jul 13, 2024
bd161e8
Merge branch 'main' of https://github.com/tangly1024/NotionNext
actions-user Jul 25, 2024
d80dc9d
Update blog.config.js
daheitian Nov 18, 2025
4e3342a
Update blog.config.js
daheitian Nov 18, 2025
9938b7f
Create .npmrc
daheitian Nov 18, 2025
2429d92
Update .env.local
daheitian Nov 18, 2025
8c72bfe
Update .env.local
daheitian Nov 18, 2025
1fac787
Create yarnrc
daheitian Nov 18, 2025
798f09e
Update and rename yarn.lock to 1
daheitian Nov 18, 2025
6bf8518
Update vercel.json
daheitian Nov 18, 2025
67cb5eb
Update vercel.json
daheitian Nov 18, 2025
aa0a441
Update blog.config.js
daheitian Nov 18, 2025
91c94f8
Update blog.config.js
daheitian Nov 18, 2025
baf00fa
Update .env.local
daheitian Nov 18, 2025
4b91c3f
Update blog.config.js
daheitian Nov 18, 2025
51d209d
Update blog.config.js
daheitian Nov 18, 2025
33791b4
Update .env.local
daheitian Nov 18, 2025
3142e85
Update blog.config.js
daheitian Nov 18, 2025
d96b111
Update .env.local
daheitian Nov 18, 2025
aa59cce
Update blog.config.js
daheitian Nov 18, 2025
c6d3308
Restore multi-language support with dynamic language detection
daheitian May 8, 2026
5a3a5da
fix(notion): normalize api.getPage result to recordMap for compatibil…
daheitian Jun 25, 2026
4912b29
fix(notion): normalize getPage result in getNotionConfig for recordMa…
daheitian Jun 25, 2026
d347214
chore: update package.json metadata to daheitian/NotionN
daheitian Jun 25, 2026
8cefecc
chore: sync package.json with upstream NotionNext v4.10.2, preserve r…
daheitian Jun 25, 2026
7e85bf3
fix: add missing lodash.throttle dependency to resolve build error
daheitian Jun 26, 2026
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions .env.local
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
# 环境变量 @see https://www.nextjs.cn/docs/basic-features/environment-variables
NEXT_PUBLIC_VERSION=4.6.1


# 可在此添加环境变量,去掉最左边的(# )注释即可
# Notion页面ID,必须
# NOTION_PAGE_ID=097e5f674880459d8e1b4407758dc4fb
NOTION_PAGE_ID=7280c13037e8477e9dd52ec1c733357e

# 主题配置
NEXT_PUBLIC_THEME=fukasawa
NEXT_PUBLIC_LANG=zh-CN
NEXT_PUBLIC_APPEARANCE=auto


# 非必须
# NEXT_PUBLIC_PSEUDO_STATIC=
Expand Down
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
registry=https://registry.npmjs.org/
1 change: 1 addition & 0 deletions 1
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

28 changes: 14 additions & 14 deletions blog.config.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
// 注: process.env.XX是Vercel的环境变量,配置方式见:https://docs.tangly1024.com/article/how-to-config-notion-next#c4768010ae7d44609b744e79e2f9959a
const BLOG = {
// Important page_id!!!Duplicate Template from https://www.notion.so/tanghh/02ab3b8678004aa69e9e415905ef32a5
// Important page_id!!!Duplicate Template from https://buerc.notion.site/7280c13037e8477e9dd52ec1c733357e?v=0447f516e8f34dabaafa920e5079a163
NOTION_PAGE_ID:
process.env.NOTION_PAGE_ID ||
'02ab3b8678004aa69e9e415905ef32a5,en:7c1d570661754c8fbc568e00a01fd70e',
'7280c13037e8477e9dd52ec1c733357e,en:0447f516e8f34dabaafa920e5079a163',
PSEUDO_STATIC: process.env.NEXT_PUBLIC_PSEUDO_STATIC || false, // 伪静态路径,开启后所有文章URL都以 .html 结尾。
NEXT_REVALIDATE_SECOND: process.env.NEXT_PUBLIC_REVALIDATE_SECOND || 5, // 更新内容缓存间隔 单位(秒);即每个页面有5秒的纯静态期、此期间无论多少次访问都不会抓取notion数据;调大该值有助于节省Vercel资源、同时提升访问速率,但也会使文章更新有延迟。
THEME: process.env.NEXT_PUBLIC_THEME || 'simple', // 当前主题,在themes文件夹下可找到所有支持的主题;主题名称就是文件夹名,例如 example,fukasawa,gitbook,heo,hexo,landing,matery,medium,next,nobelium,plog,simple
THEME: process.env.NEXT_PUBLIC_THEME || 'fukasawa', // 当前主题,在themes文件夹下可找到所有支持的主题;主题名称就是文件夹名,例如 example,fukasawa,gitbook,heo,hexo,landing,matery,medium,next,nobelium,plog,simple
THEME_SWITCH: process.env.NEXT_PUBLIC_THEME_SWITCH || false, // 是否显示切换主题按钮
LANG: process.env.NEXT_PUBLIC_LANG || 'zh-CN', // e.g 'zh-CN','en-US' see /lib/lang.js for more.
SINCE: process.env.NEXT_PUBLIC_SINCE || 2021, // e.g if leave this empty, current year will be used.
SINCE: process.env.NEXT_PUBLIC_SINCE || 2025, // e.g if leave this empty, current year will be used.
APPEARANCE: process.env.NEXT_PUBLIC_APPEARANCE || 'light', // ['light', 'dark', 'auto'], // light 日间模式 , dark夜间模式, auto根据时间和主题自动夜间模式
APPEARANCE_DARK_TIME: process.env.NEXT_PUBLIC_APPEARANCE_DARK_TIME || [18, 6], // 夜间模式起至时间,false时关闭根据时间自动切换夜间模式

Expand All @@ -20,17 +20,17 @@ const BLOG = {
// 3.14.1版本后,欢迎语在此配置,英文逗号隔开 , 即可支持多个欢迎语打字效果。
GREETING_WORDS:
process.env.NEXT_PUBLIC_GREETING_WORDS ||
'Hi,我是一个程序员, Hi,我是一个打工人,Hi,我是一个干饭人,欢迎来到我的博客🎉',
'小信号',

CUSTOM_MENU: process.env.NEXT_PUBLIC_CUSTOM_MENU || false, // 支持Menu 类型,从3.12.0版本起,各主题将逐步支持灵活的二级菜单配置,替代了原来的Page类型,此配置是试验功能、默认关闭。

AUTHOR: process.env.NEXT_PUBLIC_AUTHOR || 'NotionNext', // 您的昵称 例如 tangly1024
BIO: process.env.NEXT_PUBLIC_BIO || '一个普通的干饭人🍚', // 作者简介
LINK: process.env.NEXT_PUBLIC_LINK || 'https://tangly1024.com', // 网站地址
AUTHOR: process.env.NEXT_PUBLIC_AUTHOR || '小信号', // 您的昵称 例如 tangly1024
BIO: process.env.NEXT_PUBLIC_BIO || '设计 思考 写作', // 作者简介
LINK: process.env.NEXT_PUBLIC_LINK || 'https://xiaoxinhao.top', // 网站地址
KEYWORDS: process.env.NEXT_PUBLIC_KEYWORD || 'Notion, 博客', // 网站关键词 英文逗号隔开

// 社交链接,不需要可留空白,例如 CONTACT_WEIBO:''
CONTACT_EMAIL: process.env.NEXT_PUBLIC_CONTACT_EMAIL || '', // 邮箱地址 例如mail@tangly1024.com
CONTACT_EMAIL: process.env.NEXT_PUBLIC_CONTACT_EMAIL || '405001965@qq.com', // 邮箱地址 例如mail@tangly1024.com
CONTACT_WEIBO: process.env.NEXT_PUBLIC_CONTACT_WEIBO || '', // 你的微博个人主页
CONTACT_TWITTER: process.env.NEXT_PUBLIC_CONTACT_TWITTER || '', // 你的twitter个人主页
CONTACT_GITHUB: process.env.NEXT_PUBLIC_CONTACT_GITHUB || '', // 你的github个人主页 例如 https://github.com/tangly1024
Expand Down Expand Up @@ -251,7 +251,7 @@ const BLOG = {
],

// 鼠标跟随特效
MOUSE_FOLLOW: process.env.NEXT_PUBLIC_MOUSE_FOLLOW || true, // 开关
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
Expand Down Expand Up @@ -289,7 +289,7 @@ const BLOG = {
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: process.env.NEXT_PUBLIC_WIDGET_PET || false, // 是否显示宠物挂件
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
Expand Down Expand Up @@ -545,9 +545,9 @@ const BLOG = {
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) isProd: process.env.VERCEL_ENV === 'production' // distinguish between development and production environment (ref: https://vercel.com/docs/environment-variables#system-environment-variables)
BUNDLE_ANALYZER: process.env.ANALYZE === 'true' || false, // 是否展示编译依赖内容与大小
VERSION: process.env.NEXT_PUBLIC_VERSION // 版本号
isProd: process.env.VERCEL_ENV === 'production' || process.env.EXPORT, // distinguish between development and production environment
BUNDLE_ANALYZER: process.env.ANALYZE === 'true' || false, // 是否展示编译依赖内容与大小
VERSION: process.env.NEXT_PUBLIC_VERSION // 版本号
}

module.exports = BLOG
55 changes: 46 additions & 9 deletions lib/notion/getNotionConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,18 @@ import { deepClone } from '../utils'
import getAllPageIds from './getAllPageIds'
import { getPage } from './getPostBlocks'

function normalizeRecordMap(pageData) {
// Normalize different shapes returned by notion-client / Notion backend
if (!pageData) return null
if (pageData.recordMap) return pageData.recordMap
// Some versions may return an object with top-level `block` already
if (pageData.block) return pageData
// Some endpoints may wrap recordMap under recordMapWithRoles.recordMap
if (pageData.recordMapWithRoles && pageData.recordMapWithRoles.recordMap)
return pageData.recordMapWithRoles.recordMap
return pageData
}

/**
* 从Notion中读取Config配置表
* @param {*} allPages
Expand Down Expand Up @@ -42,19 +54,44 @@ export async function getConfigMapFromConfigPage(allPages) {
const configPageId = configPage.id
// console.log('[Notion配置]请求配置数据 ', configPage.id)
let pageRecordMap = await getPage(configPageId, 'config-table')
// console.log('配置中心Page', configPageId, pageRecordMap)
let content = pageRecordMap.block[configPageId].value.content
for (const table of ['Config-Table', 'CONFIG-TABLE']) {
if (content) break
pageRecordMap = await getPage(configPageId, table)
pageRecordMap = normalizeRecordMap(pageRecordMap)

// defensive check
if (!pageRecordMap || !pageRecordMap.block) {
// try alternative table keys
for (const table of ['Config-Table', 'CONFIG-TABLE']) {
try {
const tmp = await getPage(configPageId, table)
pageRecordMap = normalizeRecordMap(tmp)
if (pageRecordMap && pageRecordMap.block) break
} catch (e) {
// ignore and continue
}
}
}

if (!pageRecordMap || !pageRecordMap.block) {
console.warn(
'[Notion配置] 未找到配置表格或页面内容,返回 null',
configPageId,
pageRecordMap
)
return null
}

let content
try {
content = pageRecordMap.block[configPageId].value.content
} catch (err) {
console.warn('[Notion配置] 无法读取 pageRecordMap.block[configPageId].value.content', err)
return null
}

if (!content) {
console.warn(
'[Notion配置] 未找到配置表格',
pageRecordMap.block[configPageId],
pageRecordMap.block[configPageId].value
pageRecordMap.block[configPageId] && pageRecordMap.block[configPageId].value
)
return null
}
Expand All @@ -69,15 +106,15 @@ export async function getConfigMapFromConfigPage(allPages) {
console.warn(
'[Notion配置]未找到配置表格数据',
pageRecordMap.block[configPageId],
pageRecordMap.block[configPageId].value
pageRecordMap.block[configPageId] && pageRecordMap.block[configPageId].value
)
return null
}

// 页面查找
const databaseRecordMap = pageRecordMap.block[configTableId]
const block = pageRecordMap.block || {}
const rawMetadata = databaseRecordMap.value
const rawMetadata = databaseRecordMap && databaseRecordMap.value
// Check Type Page-Database和Inline-Database
if (
rawMetadata?.type !== 'collection_view_page' &&
Expand All @@ -88,7 +125,7 @@ export async function getConfigMapFromConfigPage(allPages) {
}
// console.log('表格', databaseRecordMap, block, rawMetadata)
const collectionId = rawMetadata?.collection_id
const collection = pageRecordMap.collection[collectionId].value
const collection = pageRecordMap.collection && pageRecordMap.collection[collectionId] && pageRecordMap.collection[collectionId].value
const collectionQuery = pageRecordMap.collection_query
const collectionView = pageRecordMap.collection_view
const schema = collection?.schema
Expand Down
11 changes: 11 additions & 0 deletions lib/notion/getPostBlocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,17 @@ export async function getPageWithRetry(id, from, retryAttempts = 3) {
const pageData = await api.getPage(id)
const end = new Date().getTime()
console.log('[API<<--响应]', `耗时:${end - start}ms - from:${from}`)

// NOTE: Notion API / notion-client may return different shapes over time.
// Older code expects a `recordMap`-like object (with `.block`) while some
// responses previously returned a top-level `block` directly. Normalize
// here to return the recordMap when available so the rest of code that
// expects `page.block` continues to work.
if (pageData && pageData.recordMap) {
return pageData.recordMap
}

// fallback to returning pageData as-is
return pageData
} catch (e) {
console.warn('[API<<--异常]:', e)
Expand Down
3 changes: 2 additions & 1 deletion next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ const themes = scanSubdirectories(path.resolve(__dirname, 'themes'))
const locales = (function () {
// 根据BLOG_NOTION_PAGE_ID 检查支持多少种语言数据.
// 支持如下格式配置多个语言的页面id xxx,zh:xxx,en:xxx
const langs = ['zh', 'en']
const defaultLocale = BLOG.LANG.slice(0, 2)
const langs = [defaultLocale]
if (BLOG.NOTION_PAGE_ID.indexOf(',') > 0) {
const siteIds = BLOG.NOTION_PAGE_ID.split(',')
for (let index = 0; index < siteIds.length; index++) {
Expand Down
Loading