mirror of
https://github.com/d0zingcat/nextjs-notion-starter-kit.git
synced 2026-05-13 15:09:47 +00:00
feat: WIP custom header nav
This commit is contained in:
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
# Optional (for persisting preview images to redis)
|
# Optional (for persisting preview images to redis)
|
||||||
# NOTE: if you want to enable redis, only REDIS_HOST and REDIS_PASSWORD are required
|
# NOTE: if you want to enable redis, only REDIS_HOST and REDIS_PASSWORD are required
|
||||||
# NOTE: don't forget to set isRedisEnabled to true in the site.config.js file
|
# NOTE: don't forget to set isRedisEnabled to true in the site.config.ts file
|
||||||
#REDIS_HOST=
|
#REDIS_HOST=
|
||||||
#REDIS_PASSWORD=
|
#REDIS_PASSWORD=
|
||||||
#REDIS_USER='default'
|
#REDIS_USER='default'
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import { PageHead } from './PageHead'
|
|||||||
import { PageActions } from './PageActions'
|
import { PageActions } from './PageActions'
|
||||||
import { Footer } from './Footer'
|
import { Footer } from './Footer'
|
||||||
import { PageSocial } from './PageSocial'
|
import { PageSocial } from './PageSocial'
|
||||||
|
import { NotionPageHeader } from './NotionPageHeader'
|
||||||
import { GitHubShareButton } from './GitHubShareButton'
|
import { GitHubShareButton } from './GitHubShareButton'
|
||||||
|
|
||||||
import styles from './styles.module.css'
|
import styles from './styles.module.css'
|
||||||
@@ -181,7 +182,8 @@ export const NotionPage: React.FC<types.PageProps> = ({
|
|||||||
Equation,
|
Equation,
|
||||||
Pdf,
|
Pdf,
|
||||||
Modal,
|
Modal,
|
||||||
Tweet
|
Tweet,
|
||||||
|
Header: NotionPageHeader
|
||||||
}}
|
}}
|
||||||
recordMap={recordMap}
|
recordMap={recordMap}
|
||||||
rootPageId={site.rootNotionPageId}
|
rootPageId={site.rootNotionPageId}
|
||||||
|
|||||||
26
components/NotionPageHeader.tsx
Normal file
26
components/NotionPageHeader.tsx
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import React from 'react'
|
||||||
|
// import useDarkMode from '@fisch0920/use-dark-mode'
|
||||||
|
|
||||||
|
import { Header, Breadcrumbs, Search } from 'react-notion-x'
|
||||||
|
|
||||||
|
import * as types from 'lib/types'
|
||||||
|
import { navigationStyle } from 'lib/config'
|
||||||
|
|
||||||
|
// import styles from './styles.module.css'
|
||||||
|
|
||||||
|
export const NotionPageHeader: React.FC<{
|
||||||
|
block: types.CollectionViewPageBlock | types.PageBlock
|
||||||
|
}> = ({ block }) => {
|
||||||
|
if (navigationStyle === 'default') {
|
||||||
|
return <Header block={block} />
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<header className='notion-header'>
|
||||||
|
<div className='notion-nav-header'>
|
||||||
|
<Breadcrumbs block={block} rootOnly={true} />
|
||||||
|
<Search block={block} />
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,14 +1,18 @@
|
|||||||
/**
|
/**
|
||||||
* Site-wide app configuration.
|
* Site-wide app configuration.
|
||||||
*
|
*
|
||||||
* This file pulls from the root "site.config.js" as well as environment variables
|
* This file pulls from the root "site.config.ts" as well as environment variables
|
||||||
* for optional depenencies.
|
* for optional depenencies.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { parsePageId } from 'notion-utils'
|
import { parsePageId } from 'notion-utils'
|
||||||
import posthog from 'posthog-js'
|
import posthog from 'posthog-js'
|
||||||
import { getEnv, getSiteConfig } from './get-config-value'
|
import { getEnv, getSiteConfig } from './get-config-value'
|
||||||
import { PageUrlOverridesInverseMap, PageUrlOverridesMap } from './types'
|
import {
|
||||||
|
PageUrlOverridesInverseMap,
|
||||||
|
PageUrlOverridesMap,
|
||||||
|
NavigationStyle
|
||||||
|
} from './types'
|
||||||
|
|
||||||
export const rootNotionPageId: string = parsePageId(
|
export const rootNotionPageId: string = parsePageId(
|
||||||
getSiteConfig('rootNotionPageId'),
|
getSiteConfig('rootNotionPageId'),
|
||||||
@@ -48,9 +52,9 @@ export const description: string = getSiteConfig('description', 'Notion Blog')
|
|||||||
|
|
||||||
// social accounts
|
// social accounts
|
||||||
export const twitter: string | null = getSiteConfig('twitter', null)
|
export const twitter: string | null = getSiteConfig('twitter', null)
|
||||||
export const zhihu: string | null = getSiteConfig('zhihu', null)
|
|
||||||
export const github: string | null = getSiteConfig('github', null)
|
export const github: string | null = getSiteConfig('github', null)
|
||||||
export const linkedin: string | null = getSiteConfig('linkedin', null)
|
export const linkedin: string | null = getSiteConfig('linkedin', null)
|
||||||
|
export const zhihu: string | null = getSiteConfig('zhihu', null)
|
||||||
|
|
||||||
// default notion values for site-wide consistency (optional; may be overridden on a per-page basis)
|
// default notion values for site-wide consistency (optional; may be overridden on a per-page basis)
|
||||||
export const defaultPageIcon: string | null = getSiteConfig(
|
export const defaultPageIcon: string | null = getSiteConfig(
|
||||||
@@ -78,12 +82,17 @@ export const isTweetEmbedSupportEnabled: boolean = getSiteConfig(
|
|||||||
true
|
true
|
||||||
)
|
)
|
||||||
|
|
||||||
// where it all starts -- the site's root Notion page
|
// Optional whether or not to include the Notion ID in page URLs or just use slugs
|
||||||
export const includeNotionIdInUrls: boolean = getSiteConfig(
|
export const includeNotionIdInUrls: boolean = getSiteConfig(
|
||||||
'includeNotionIdInUrls',
|
'includeNotionIdInUrls',
|
||||||
!!isDev
|
!!isDev
|
||||||
)
|
)
|
||||||
|
|
||||||
|
export const navigationStyle: NavigationStyle = getSiteConfig(
|
||||||
|
'navigationStyle',
|
||||||
|
'default'
|
||||||
|
)
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
// Optional redis instance for persisting preview images
|
// Optional redis instance for persisting preview images
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
import rawSiteConfig from '../site.config'
|
import rawSiteConfig from '../site.config'
|
||||||
|
import { SiteConfig } from './site-config'
|
||||||
|
|
||||||
if (!rawSiteConfig) {
|
if (!rawSiteConfig) {
|
||||||
throw new Error(`Config error: invalid site.config.js`)
|
throw new Error(`Config error: invalid site.config.ts`)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: allow environment variables to override site.config.js
|
// allow environment variables to override site.config.ts
|
||||||
let siteConfigOverrides
|
let siteConfigOverrides: SiteConfig
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (process.env.NEXT_PUBLIC_SITE_CONFIG) {
|
if (process.env.NEXT_PUBLIC_SITE_CONFIG) {
|
||||||
@@ -16,7 +17,7 @@ try {
|
|||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
|
|
||||||
const siteConfig = {
|
const siteConfig: SiteConfig = {
|
||||||
...rawSiteConfig,
|
...rawSiteConfig,
|
||||||
...siteConfigOverrides
|
...siteConfigOverrides
|
||||||
}
|
}
|
||||||
|
|||||||
34
lib/site-config.ts
Normal file
34
lib/site-config.ts
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import * as types from './types'
|
||||||
|
|
||||||
|
export interface SiteConfig {
|
||||||
|
rootNotionPageId: string
|
||||||
|
rootNotionSpaceId?: string
|
||||||
|
|
||||||
|
name: string
|
||||||
|
domain: string
|
||||||
|
author: string
|
||||||
|
description?: string
|
||||||
|
|
||||||
|
twitter?: string
|
||||||
|
github?: string
|
||||||
|
linkedin?: string
|
||||||
|
zhihu?: string
|
||||||
|
|
||||||
|
defaultPageIcon?: string | null
|
||||||
|
defaultPageCover?: string | null
|
||||||
|
defaultPageCoverPosition?: number | null
|
||||||
|
|
||||||
|
isPreviewImageSupportEnabled?: boolean
|
||||||
|
isTweetEmbedSupportEnabled?: boolean
|
||||||
|
isRedisEnabled?: boolean
|
||||||
|
|
||||||
|
includeNotionIdInUrls?: boolean
|
||||||
|
pageUrlOverrides?: types.PageUrlOverridesMap
|
||||||
|
pageUrlAdditions?: types.PageUrlOverridesMap
|
||||||
|
|
||||||
|
navigationStyle?: types.NavigationStyle
|
||||||
|
}
|
||||||
|
|
||||||
|
export const siteConfig = (config: SiteConfig): SiteConfig => {
|
||||||
|
return config
|
||||||
|
}
|
||||||
@@ -2,6 +2,8 @@ import { ExtendedRecordMap, PageMap } from 'notion-types'
|
|||||||
|
|
||||||
export * from 'notion-types'
|
export * from 'notion-types'
|
||||||
|
|
||||||
|
export type NavigationStyle = 'default' | 'custom'
|
||||||
|
|
||||||
export interface PageError {
|
export interface PageError {
|
||||||
message?: string
|
message?: string
|
||||||
statusCode: number
|
statusCode: number
|
||||||
|
|||||||
10
readme.md
10
readme.md
@@ -18,7 +18,7 @@ It uses Notion as a CMS, [react-notion-x](https://github.com/NotionX/react-notio
|
|||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- Setup only takes a few minutes ([single config file](./site.config.js)) 💪
|
- Setup only takes a few minutes ([single config file](./site.config.ts)) 💪
|
||||||
- Robust support for Notion content via [react-notion-x](https://github.com/NotionX/react-notion-x)
|
- Robust support for Notion content via [react-notion-x](https://github.com/NotionX/react-notion-x)
|
||||||
- Built using Next.js, TS, and React
|
- Built using Next.js, TS, and React
|
||||||
- Excellent page speeds
|
- Excellent page speeds
|
||||||
@@ -38,12 +38,12 @@ It uses Notion as a CMS, [react-notion-x](https://github.com/NotionX/react-notio
|
|||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
|
|
||||||
**All config is defined in [site.config.js](./site.config.js).**
|
**All config is defined in [site.config.ts](./site.config.ts).**
|
||||||
|
|
||||||
This project requires a recent version of Node.js (>= 14.17).
|
This project requires a recent version of Node.js (>= 14.17).
|
||||||
|
|
||||||
1. Fork / clone this repo
|
1. Fork / clone this repo
|
||||||
2. Change a few values in [site.config.js](./site.config.js)
|
2. Change a few values in [site.config.ts](./site.config.ts)
|
||||||
3. `npm install`
|
3. `npm install`
|
||||||
4. `npm run dev` to test locally
|
4. `npm run dev` to test locally
|
||||||
5. `npm run deploy` to deploy to vercel 💪
|
5. `npm run deploy` to deploy to vercel 💪
|
||||||
@@ -82,11 +82,11 @@ NOTE: if you have multiple pages in your workspace with the same slugified name,
|
|||||||
|
|
||||||
We use [next/image](https://nextjs.org/docs/api-reference/next/image) to serve images efficiently, with preview images optionally generated via [lqip-modern](https://github.com/transitive-bullshit/lqip-modern). This gives us extremely optimized image support for sexy smooth images.
|
We use [next/image](https://nextjs.org/docs/api-reference/next/image) to serve images efficiently, with preview images optionally generated via [lqip-modern](https://github.com/transitive-bullshit/lqip-modern). This gives us extremely optimized image support for sexy smooth images.
|
||||||
|
|
||||||
Preview images are **enabled by default**, but they can be slow to generate, so if you want to disable them, set `isPreviewImageSupportEnabled` to `false` in `site.config.js`.
|
Preview images are **enabled by default**, but they can be slow to generate, so if you want to disable them, set `isPreviewImageSupportEnabled` to `false` in `site.config.ts`.
|
||||||
|
|
||||||
### Redis
|
### Redis
|
||||||
|
|
||||||
If you want to cache generated preview images to speed up subsequent builds, you'll need to first set up an external [Redis](https://redis.io) data store. To enable redis caching, set `isRedisEnabled` to `true` in `site.config.js` and then set `REDIS_HOST` and `REDIS_PASSWORD` environment variables to point to your redis instance.
|
If you want to cache generated preview images to speed up subsequent builds, you'll need to first set up an external [Redis](https://redis.io) data store. To enable redis caching, set `isRedisEnabled` to `true` in `site.config.ts` and then set `REDIS_HOST` and `REDIS_PASSWORD` environment variables to point to your redis instance.
|
||||||
|
|
||||||
You can do this locally by adding a `.env` file:
|
You can do this locally by adding a `.env` file:
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
export default {
|
import { siteConfig } from './lib/site-config'
|
||||||
|
|
||||||
|
export default siteConfig({
|
||||||
// the site's root Notion page (required)
|
// the site's root Notion page (required)
|
||||||
rootNotionPageId: '7875426197cf461698809def95960ebf',
|
rootNotionPageId: '7875426197cf461698809def95960ebf',
|
||||||
|
|
||||||
@@ -25,6 +27,8 @@ export default {
|
|||||||
defaultPageCover: null,
|
defaultPageCover: null,
|
||||||
defaultPageCoverPosition: 0.5,
|
defaultPageCoverPosition: 0.5,
|
||||||
|
|
||||||
|
navigationStyle: 'custom',
|
||||||
|
|
||||||
// whether or not to enable support for LQIP preview images (optional)
|
// whether or not to enable support for LQIP preview images (optional)
|
||||||
isPreviewImageSupportEnabled: true,
|
isPreviewImageSupportEnabled: true,
|
||||||
|
|
||||||
@@ -42,4 +46,4 @@ export default {
|
|||||||
// '/bar': '0be6efce9daf42688f65c76b89f8eb27'
|
// '/bar': '0be6efce9daf42688f65c76b89f8eb27'
|
||||||
// }
|
// }
|
||||||
pageUrlOverrides: null
|
pageUrlOverrides: null
|
||||||
}
|
})
|
||||||
@@ -39,7 +39,7 @@
|
|||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.notion-header .nav-header {
|
.notion-header .notion-nav-header {
|
||||||
max-width: 1100px;
|
max-width: 1100px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,5 +19,5 @@
|
|||||||
"incremental": true
|
"incremental": true
|
||||||
},
|
},
|
||||||
"exclude": ["node_modules"],
|
"exclude": ["node_modules"],
|
||||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"]
|
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "site.config.ts"]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user