mirror of
https://github.com/d0zingcat/NotionNext.git
synced 2026-05-14 15:09:22 +00:00
75
README.md
75
README.md
@@ -1,7 +1,5 @@
|
||||
# NotionNext
|
||||
|
||||
一个使用 NextJS + Notion API 实现的,部署在 Vercel 上的静态博客系统。为Notion和所有创作者设计。
|
||||
|
||||
<p>
|
||||
<a aria-label="GitHub commit activity" href="https://github.com/tangly1024/NotionNext/commits/main" title="GitHub commit activity">
|
||||
<img src="https://img.shields.io/github/commit-activity/m/tangly1024/NotionNext?style=for-the-badge"/>
|
||||
@@ -17,74 +15,20 @@
|
||||
</a>
|
||||
</p>
|
||||
|
||||
演示地址:[https://preview.tangly1024.com/](https://preview.tangly1024.com/)
|
||||
一个使用 NextJS + Notion API 实现的,部署在 Vercel 上的静态博客系统。为Notion和所有创作者设计。
|
||||
|
||||
## 继承自Nobelium的亮点 ✨
|
||||
|
||||
**🚀 秒开,设备全适配**
|
||||
## 预览效果
|
||||
|
||||
- 快速的页面渲染和响应式设计
|
||||
- 高效编译器的快速静态页面生成
|
||||
|
||||
**🤖 自动,无需重新部署**
|
||||
|
||||
- 部署在免费、高速的 Vercel 平台
|
||||
- 支持增量式更新,更新文章后无需重复部署
|
||||
|
||||
**🚙 全功能,完全不操心**
|
||||
|
||||
- 评论、搜索、标签、分类
|
||||
- 订阅、网站统计
|
||||
- 本地化多语言
|
||||
- 服务端渲染、优秀的SEO
|
||||
|
||||
**🎨 美观,轻松自定义**
|
||||
- 丰富的配置项,更支持多语言
|
||||
- 使用 Tailwind CSS,轻松实现二次开发
|
||||
|
||||
## 特色
|
||||
- 支持更多的页面,功能,更多特性、欢迎移步[我的博客](https://tangly1024.com/article/notion-next)查看
|
||||
- 支持多主题切换
|
||||
在线演示:[https://preview.tangly1024.com/](https://preview.tangly1024.com/) ,项目支持多主题切换,没找到喜欢的主题?[贡献](/CONTRIBUTING.md)一个吧~
|
||||
|
||||
| Next | Medium | Hexo | Fukasawa |
|
||||
|--|--|--|--|
|
||||
| <img src='./docs/theme-next.png' width='300'/> [预览NEXT](https://preview.tangly1024.com/?theme=next) | <img src='./docs/theme-medium.png' width='300'/> [预览MEDIUM](https://preview.tangly1024.com/?theme=medium) | <img src='./docs/theme-hexo.png' width='300'/> [预览HEXO](https://preview.tangly1024.com/?theme=hexo) | <img src='./docs/theme-fukasawa.png' width='300'/> [预览FUKASAWA](https://preview.tangly1024.com/?theme=fukasawa) |
|
||||
|
||||
*只需修改`blog.config.js`文件的`THEME`即可实现主题切换。* 没找到喜欢的主题?[贡献](/CONTRIBUTING.md)一个吧~
|
||||
## 我要如何开始?
|
||||
|
||||
|
||||
|
||||
## 快速起步
|
||||
|
||||
- 给这个项目点个小星星 😉
|
||||
- 将 [这个 Notion 模板](https://tanghh.notion.site/02ab3b8678004aa69e9e415905ef32a5) 制作副本,并分享这个页面给所有人
|
||||
- [Fork](https://github.com/tangly1024/NotionNext/fork) 这个项目
|
||||
- _(可选)_ 用自己的图片替换 `/public` 文件夹里的 `avatar.jpg`、`favicon.svg` 和 `favicon.ico`
|
||||
- 在 `blog.config.js` 配置相关选项,`NOTION_PAGE_ID`: 你刚刚分享出去的 Notion 页面网址中的页面 ID,通常是网址中工作区地址后的 32 位字符串
|
||||
- 在 [Vercel](https://vercel.com)中部署项目
|
||||
- **稍微等等就可以访问了!** 简单吗?
|
||||
|
||||
更多项目特性及配置的说明,请移步 [NotionNext文档](https://docs.tangly1024.com/zh) 查看,文档正在完善中,欢迎 [参与编辑](https://github.com/tangly1024/nextjs-docs-notion-next)
|
||||
|
||||
## 快速开发
|
||||
- 需要安装Nodejs环境
|
||||
```bash
|
||||
yarn # 安装依赖
|
||||
yarn run dev # 本地开发
|
||||
yarn run build # 本地打包编译
|
||||
yarn run start # 本地启动NextJS服务
|
||||
```
|
||||
|
||||
## 引用技术
|
||||
|
||||
- **框架**: [Next.js](https://nextjs.org)
|
||||
- **样式**: [Tailwind CSS](https://www.tailwindcss.cn/) 和 `@tailwindcss/jit` compiler
|
||||
- **渲染**: [React-notion-x](https://github.com/NotionX/react-notion-x)
|
||||
- **评论**: [Giscus](https://giscus.app/zh-CN), [Gitalk](https://gitalk.github.io), [Cusdis](https://cusdis.com), [Utterances](https://utteranc.es)
|
||||
- **图标**:[fontawesome v5.15](https://fontawesome.com/v5.15/icons?d=gallery)
|
||||
|
||||
## 更新日志
|
||||
请移步 [更新文档](https://docs.tangly1024.com/zh/changelog)查看
|
||||
只需几分钟即可搭建您的个人站点,欢迎移步[我的博客](https://tangly1024.com/article/notion-next) 查看教程
|
||||
|
||||
|
||||
## 致谢
|
||||
@@ -120,12 +64,17 @@ yarn run start # 本地启动NextJS服务
|
||||
<td align="center"><a href="https://github.com/SwwweetOrange"><img src="https://avatars.githubusercontent.com/u/71168966" width="64px;" alt="SwwweetOrange"/><br/><sub><b>SwwweetOrange</b></sub></a><br/><a href="https://github.com/tangly1024/NotionNext/commits?author=SwwweetOrange" title="SwwweetOrange" >🔧 🐛</a></td>
|
||||
|
||||
<td align="center"><a href="https://github.com/Ylarod"><img src="https://avatars.githubusercontent.com/u/30978685" width="64px;" alt="Ylarod"/><br/><sub><b>Ylarod</b></sub></a><br/><a href="https://github.com/tangly1024/NotionNext/commits?author=Ylarod" title="Ylarod" >🔧 🐛</a></td>
|
||||
v
|
||||
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
十分期待你的[贡献](/CONTRIBUTING.md),一起来完善这个项目~
|
||||
## 引用技术
|
||||
|
||||
- **框架**: [Next.js](https://nextjs.org)
|
||||
- **样式**: [Tailwind CSS](https://www.tailwindcss.cn/) 和 `@tailwindcss/jit` compiler
|
||||
- **渲染**: [React-notion-x](https://github.com/NotionX/react-notion-x)
|
||||
- **评论**: [Giscus](https://giscus.app/zh-CN), [Gitalk](https://gitalk.github.io), [Cusdis](https://cusdis.com), [Utterances](https://utteranc.es)
|
||||
- **图标**: [Fontawesome](https://fontawesome.com/v6/icons/)
|
||||
|
||||
|
||||
## License
|
||||
|
||||
@@ -66,7 +66,13 @@ const BLOG = {
|
||||
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: true, // 点击宠物挂件切换博客主题
|
||||
|
||||
// 评论互动 可同时开启多个支持 GISCUS CUSDIS UTTERRANCES GITALK
|
||||
// ----> 评论互动 可同时开启多个支持 WALINE VALINE GISCUS CUSDIS UTTERRANCES GITALK
|
||||
|
||||
// twikoo
|
||||
COMMENT_TWIKOO_ENV_ID: process.env.NEXT_PUBLIC_COMMENT_ENV_ID || '', // TWIKOO地址 腾讯云环境填 envId;Vercel 环境域名地址(https://xxx.vercel.app)
|
||||
|
||||
// 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'
|
||||
@@ -84,8 +90,6 @@ const BLOG = {
|
||||
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 || 'https://cusdis.com/js/cusdis.es.js', // change this if you're using self-hosted version
|
||||
|
||||
COMMENT_UTTERRANCES_REPO: process.env.NEXT_PUBLIC_COMMENT_UTTERRANCES_REPO || '', // 你的代码仓库名, 例如我是 'tangly1024/NotionNext'; 更多文档参考 https://utteranc.es/
|
||||
|
||||
// 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
|
||||
@@ -106,7 +110,9 @@ const BLOG = {
|
||||
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, // 最新评论
|
||||
|
||||
// 站点统计
|
||||
// <---- 评论插件
|
||||
|
||||
// ----> 站点统计
|
||||
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]
|
||||
@@ -118,6 +124,8 @@ const BLOG = {
|
||||
|
||||
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
|
||||
|
||||
// <---- 站点统计
|
||||
|
||||
// 谷歌广告
|
||||
ADSENSE_GOOGLE_ID: process.env.NEXT_PUBLIC_ADSENSE_GOOGLE_ID || '', // 谷歌广告ID e.g ca-pub-xxxxxxxxxxxxxxxx
|
||||
|
||||
|
||||
@@ -19,6 +19,13 @@ const CusdisComponent = dynamic(
|
||||
{ ssr: false }
|
||||
)
|
||||
|
||||
const TwikooCompenent = dynamic(
|
||||
() => {
|
||||
return import('@/components/Twikoo')
|
||||
},
|
||||
{ ssr: false }
|
||||
)
|
||||
|
||||
const GitalkComponent = dynamic(
|
||||
() => {
|
||||
return import('@/components/Gitalk')
|
||||
@@ -66,6 +73,10 @@ const Comment = ({ frontMatter }) => {
|
||||
<div id='comment' className='comment mt-5 text-gray-800 dark:text-gray-300'>
|
||||
<Tabs>
|
||||
|
||||
{ BLOG.COMMENT_TWIKOO_ENV_ID && (<div key='Twikoo'>
|
||||
<TwikooCompenent/>
|
||||
</div>)}
|
||||
|
||||
{ BLOG.COMMENT_WALINE_SERVER_URL && (<div key='Waline'>
|
||||
<WalineComponent/>
|
||||
</div>) }
|
||||
|
||||
27
components/Twikoo.js
Normal file
27
components/Twikoo.js
Normal file
@@ -0,0 +1,27 @@
|
||||
import BLOG from '@/blog.config'
|
||||
import React from 'react'
|
||||
import twikoo from 'twikoo'
|
||||
|
||||
/**
|
||||
* Giscus评论 @see https://giscus.app/zh-CN
|
||||
* Contribute by @txs https://github.com/txs/NotionNext/commit/1bf7179d0af21fb433e4c7773504f244998678cb
|
||||
* @returns {JSX.Element}
|
||||
* @constructor
|
||||
*/
|
||||
|
||||
const Twikoo = ({ isDarkMode }) => {
|
||||
React.useEffect(() => {
|
||||
twikoo({
|
||||
envId: BLOG.COMMENT_TWIKOO_ENV_ID, // 腾讯云环境填 envId;Vercel 环境填地址(https://xxx.vercel.app)
|
||||
el: '#twikoo', // 容器元素
|
||||
lang: BLOG.LANG // 用于手动设定评论区语言,支持的语言列表 https://github.com/imaegoo/twikoo/blob/main/src/client/utils/i18n/index.js
|
||||
// region: 'ap-guangzhou', // 环境地域,默认为 ap-shanghai,腾讯云环境填 ap-shanghai 或 ap-guangzhou;Vercel 环境不填
|
||||
// path: location.pathname, // 用于区分不同文章的自定义 js 路径,如果您的文章路径不是 location.pathname,需传此参数
|
||||
})
|
||||
})
|
||||
return (
|
||||
<div id="twikoo"></div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Twikoo
|
||||
@@ -52,6 +52,7 @@
|
||||
"react-notion-x": "6.15.6",
|
||||
"react-share": "^4.4.0",
|
||||
"smoothscroll-polyfill": "^0.4.4",
|
||||
"twikoo": "^1.6.8",
|
||||
"typed.js": "^2.0.12",
|
||||
"use-ackee": "^3.0.0",
|
||||
"valine": "^1.4.18"
|
||||
|
||||
@@ -132,11 +132,6 @@ nav {
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.dark .glassmorphism {
|
||||
background: rgba(31, 41, 55, 0.75);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.medium-zoom-overlay {
|
||||
background: none !important;
|
||||
|
||||
@@ -39,7 +39,7 @@ export const LayoutArchive = (props) => {
|
||||
}, [])
|
||||
return <LayoutBase {...props} >
|
||||
<Card className='w-full'>
|
||||
<div className="mb-10 pb-20 bg-white md:p-12 p-3 dark:bg-gray-800 min-h-full">
|
||||
<div className="mb-10 pb-20 bg-white md:p-12 p-3 min-h-full dark:bg-hexo-black-gray">
|
||||
{Object.keys(archivePosts).map(archiveTitle => (
|
||||
<BlogPostArchive
|
||||
key={archiveTitle}
|
||||
|
||||
@@ -16,7 +16,7 @@ const NavButtonGroup = (props) => {
|
||||
return <nav id='home-nav-button' className={'md:h-52 md:mt-6 xl:mt-32 px-5 py-2 mt-8 flex flex-wrap md:max-w-5xl space-y-2 md:space-y-0 md:flex justify-center max-h-80 overflow-auto'}>
|
||||
{categories.map(category => {
|
||||
return <Link key={`${category.name}`} title={`${category.name}`} href={`/category/${category.name}`} passHref>
|
||||
<a className='text-center w-full md:mx-6 md:w-40 md:h-14 lg:h-20 h-14 justify-center items-center flex border-2 cursor-pointer rounded-lg glassmorphism hover:bg-white hover:text-black duration-200 font-bold hover:scale-110 transform'>{category.name}</a>
|
||||
<a className='text-center w-full md:mx-6 md:w-40 md:h-14 lg:h-20 h-14 justify-center items-center flex border-2 cursor-pointer rounded-lg glassmorphism hover:bg-white hover:text-black duration-200 font-bold hover:scale-110 transform'>{category.name}</a>
|
||||
</Link>
|
||||
})}
|
||||
</nav>
|
||||
|
||||
@@ -24,7 +24,7 @@ const LayoutBase = props => {
|
||||
const router = useRouter()
|
||||
|
||||
return (
|
||||
<div className='bg-white dark:bg-black w-full h-full min-h-screen justify-center dark:text-gray-300'>
|
||||
<div className='bg-white dark:bg-hexo-black-gray w-full h-full min-h-screen justify-center dark:text-gray-300'>
|
||||
<CommonHead meta={meta} />
|
||||
<main id='wrapper' className='flex justify-between w-full h-full mx-auto'>
|
||||
{/* 桌面端左侧菜单 */}
|
||||
|
||||
@@ -9,14 +9,14 @@ export default function ArticleAround ({ prev, next }) {
|
||||
if (!prev || !next) {
|
||||
return <></>
|
||||
}
|
||||
return <section className='text-gray-800 h-12 flex items-center justify-between space-x-5 my-4'>
|
||||
return <section className='text-gray-800 dark:text-gray-400 h-12 flex items-center justify-between space-x-5 my-4'>
|
||||
<Link href={`/${prev.slug}`} passHref>
|
||||
<a className='text-sm cursor-pointer justify-start items-center flex hover:underline duration-300'>
|
||||
<i className='mr-1 fas fa-angle-double-left' />{prev.title}
|
||||
</a>
|
||||
</Link>
|
||||
<Link href={`/${next.slug}`} passHref>
|
||||
<a className='text-sm cursor-pointer justify-end items-center flex hover:underline duration-300'>{next.title}
|
||||
<a className='text-sm cursor-pointer justify-end items-center flex hover:underline duration-300'>{next.title}
|
||||
<i className='ml-1 my-1 fas fa-angle-double-right' />
|
||||
</a>
|
||||
</Link>
|
||||
|
||||
@@ -21,7 +21,7 @@ export const ArticleDetail = props => {
|
||||
return <div id='container'>
|
||||
|
||||
{/* title */}
|
||||
<h1 className="text-3xl pt-12 font-sans dark:text-gray-100">{post?.title}</h1>
|
||||
<h1 className="text-3xl pt-12 font-sans dark:text-gray-300">{post?.title}</h1>
|
||||
|
||||
{/* meta */}
|
||||
<section className="py-2 items-center text-sm font-sans px-1">
|
||||
@@ -61,6 +61,7 @@ export const ArticleDetail = props => {
|
||||
data-ad-slot="3806269138"
|
||||
/>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<div className='flex justify-between'>
|
||||
{CONFIG_MEDIUM.POST_DETAIL_CATEGORY && post.category && <CategoryItem category={post.category} />}
|
||||
|
||||
@@ -19,7 +19,7 @@ const BlogPostCard = ({ post, showSummary }) => {
|
||||
<Link href={`${BLOG.SUB_PATH}/${post.slug}`} passHref>
|
||||
<a
|
||||
className={
|
||||
'cursor-pointer font-bold font-sans hover:underline text-3xl leading-tight text-gray-700 dark:text-gray-100 hover:text-green-500 dark:hover:text-green-400'
|
||||
'cursor-pointer font-bold font-sans hover:underline text-3xl leading-tight text-gray-700 dark:text-gray-300 hover:text-green-500 dark:hover:text-green-400'
|
||||
}
|
||||
>
|
||||
{post.title}
|
||||
|
||||
Reference in New Issue
Block a user