mirror of
https://github.com/d0zingcat/nextjs-notion-starter-kit.git
synced 2026-05-13 15:09:47 +00:00
219 lines
6.3 KiB
TypeScript
219 lines
6.3 KiB
TypeScript
/**
|
|
* Site-wide app configuration.
|
|
*
|
|
* This file pulls from the root "site.config.ts" as well as environment variables
|
|
* for optional depenencies.
|
|
*/
|
|
import { parsePageId } from 'notion-utils'
|
|
import { type PostHogConfig } from 'posthog-js'
|
|
|
|
import {
|
|
getEnv,
|
|
getRequiredSiteConfig,
|
|
getSiteConfig
|
|
} from './get-config-value'
|
|
import { type NavigationLink } from './site-config'
|
|
import {
|
|
type NavigationStyle,
|
|
type PageUrlOverridesInverseMap,
|
|
type PageUrlOverridesMap,
|
|
type Site
|
|
} from './types'
|
|
|
|
export const rootNotionPageId: string = parsePageId(
|
|
getSiteConfig('rootNotionPageId'),
|
|
{ uuid: false }
|
|
)!
|
|
|
|
if (!rootNotionPageId) {
|
|
throw new Error('Config error invalid "rootNotionPageId"')
|
|
}
|
|
|
|
// if you want to restrict pages to a single notion workspace (optional)
|
|
export const rootNotionSpaceId: string | null =
|
|
parsePageId(getSiteConfig('rootNotionSpaceId'), { uuid: true }) ?? null
|
|
|
|
export const pageUrlOverrides = cleanPageUrlMap(
|
|
getSiteConfig('pageUrlOverrides', {}) || {},
|
|
{ label: 'pageUrlOverrides' }
|
|
)
|
|
|
|
export const pageUrlAdditions = cleanPageUrlMap(
|
|
getSiteConfig('pageUrlAdditions', {}) || {},
|
|
{ label: 'pageUrlAdditions' }
|
|
)
|
|
|
|
export const inversePageUrlOverrides = invertPageUrlOverrides(pageUrlOverrides)
|
|
|
|
export const environment = process.env.NODE_ENV || 'development'
|
|
export const isDev = environment === 'development'
|
|
|
|
// general site config
|
|
export const name: string = getRequiredSiteConfig('name')
|
|
export const author: string = getRequiredSiteConfig('author')
|
|
export const domain: string = getRequiredSiteConfig('domain')
|
|
export const description: string = getSiteConfig('description', 'Notion Blog')
|
|
export const language: string = getSiteConfig('language', 'en')
|
|
|
|
// social accounts
|
|
export const twitter: string | undefined = getSiteConfig('twitter')
|
|
export const mastodon: string | undefined = getSiteConfig('mastodon')
|
|
export const github: string | undefined = getSiteConfig('github')
|
|
export const youtube: string | undefined = getSiteConfig('youtube')
|
|
export const linkedin: string | undefined = getSiteConfig('linkedin')
|
|
export const newsletter: string | undefined = getSiteConfig('newsletter')
|
|
export const zhihu: string | undefined = getSiteConfig('zhihu')
|
|
|
|
export const getMastodonHandle = (): string | undefined => {
|
|
if (!mastodon) {
|
|
return
|
|
}
|
|
|
|
// Since Mastodon is decentralized, handles include the instance domain name.
|
|
// e.g. @example@mastodon.social
|
|
const url = new URL(mastodon)
|
|
return `${url.pathname.slice(1)}@${url.hostname}`
|
|
}
|
|
|
|
// default notion values for site-wide consistency (optional; may be overridden on a per-page basis)
|
|
export const defaultPageIcon: string | undefined =
|
|
getSiteConfig('defaultPageIcon')
|
|
export const defaultPageCover: string | undefined =
|
|
getSiteConfig('defaultPageCover')
|
|
export const defaultPageCoverPosition: number = getSiteConfig(
|
|
'defaultPageCoverPosition',
|
|
0.5
|
|
)
|
|
|
|
// Optional whether or not to enable support for LQIP preview images
|
|
export const isPreviewImageSupportEnabled: boolean = getSiteConfig(
|
|
'isPreviewImageSupportEnabled',
|
|
false
|
|
)
|
|
|
|
// Optional whether or not to include the Notion ID in page URLs or just use slugs
|
|
export const includeNotionIdInUrls: boolean = getSiteConfig(
|
|
'includeNotionIdInUrls',
|
|
!!isDev
|
|
)
|
|
|
|
export const navigationStyle: NavigationStyle = getSiteConfig(
|
|
'navigationStyle',
|
|
'default'
|
|
)
|
|
|
|
export const navigationLinks: Array<NavigationLink | undefined> = getSiteConfig(
|
|
'navigationLinks',
|
|
null
|
|
)
|
|
|
|
// Optional site search
|
|
export const isSearchEnabled: boolean = getSiteConfig('isSearchEnabled', true)
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// Optional redis instance for persisting preview images
|
|
export const isRedisEnabled: boolean = getSiteConfig('isRedisEnabled', false)
|
|
|
|
// (if you want to enable redis, only REDIS_HOST and REDIS_PASSWORD are required)
|
|
// we recommend that you store these in a local `.env` file
|
|
export const redisHost: string | undefined = getEnv('REDIS_HOST')
|
|
export const redisPassword: string | undefined = getEnv('REDIS_PASSWORD')
|
|
export const redisUser: string | undefined = getEnv('REDIS_USER', 'default')
|
|
export const redisUrl = getEnv(
|
|
'REDIS_URL',
|
|
`redis://${redisUser}:${redisPassword}@${redisHost}`
|
|
)
|
|
export const redisNamespace: string | undefined = getEnv(
|
|
'REDIS_NAMESPACE',
|
|
'preview-images'
|
|
)
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
export const isServer = typeof window === 'undefined'
|
|
|
|
export const port = getEnv('PORT', '3000')
|
|
export const host = isDev ? `http://localhost:${port}` : `https://${domain}`
|
|
export const apiHost = isDev
|
|
? host
|
|
: `https://${process.env.VERCEL_URL || domain}`
|
|
|
|
export const apiBaseUrl = `/api`
|
|
|
|
export const api = {
|
|
searchNotion: `${apiBaseUrl}/search-notion`,
|
|
getNotionPageInfo: `${apiBaseUrl}/notion-page-info`,
|
|
getSocialImage: `${apiBaseUrl}/social-image`
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
export const site: Site = {
|
|
domain,
|
|
name,
|
|
rootNotionPageId,
|
|
rootNotionSpaceId,
|
|
description
|
|
}
|
|
|
|
export const fathomId = isDev ? undefined : process.env.NEXT_PUBLIC_FATHOM_ID
|
|
export const fathomConfig = fathomId
|
|
? {
|
|
excludedDomains: ['localhost', 'localhost:3000']
|
|
}
|
|
: undefined
|
|
|
|
export const posthogId = process.env.NEXT_PUBLIC_POSTHOG_ID
|
|
export const posthogConfig: Partial<PostHogConfig> = {
|
|
api_host: 'https://app.posthog.com'
|
|
}
|
|
|
|
function cleanPageUrlMap(
|
|
pageUrlMap: PageUrlOverridesMap,
|
|
{
|
|
label
|
|
}: {
|
|
label: string
|
|
}
|
|
): PageUrlOverridesMap {
|
|
return Object.keys(pageUrlMap).reduce((acc, uri) => {
|
|
const pageId = pageUrlMap[uri]
|
|
const uuid = parsePageId(pageId, { uuid: false })
|
|
|
|
if (!uuid) {
|
|
throw new Error(`Invalid ${label} page id "${pageId}"`)
|
|
}
|
|
|
|
if (!uri) {
|
|
throw new Error(`Missing ${label} value for page "${pageId}"`)
|
|
}
|
|
|
|
if (!uri.startsWith('/')) {
|
|
throw new Error(
|
|
`Invalid ${label} value for page "${pageId}": value "${uri}" should be a relative URI that starts with "/"`
|
|
)
|
|
}
|
|
|
|
const path = uri.slice(1)
|
|
|
|
return {
|
|
...acc,
|
|
[path]: uuid
|
|
}
|
|
}, {})
|
|
}
|
|
|
|
function invertPageUrlOverrides(
|
|
pageUrlOverrides: PageUrlOverridesMap
|
|
): PageUrlOverridesInverseMap {
|
|
return Object.keys(pageUrlOverrides).reduce((acc, uri) => {
|
|
const pageId = pageUrlOverrides[uri]!
|
|
|
|
return {
|
|
...acc,
|
|
[pageId]: uri
|
|
}
|
|
}, {})
|
|
}
|