mirror of
https://github.com/d0zingcat/nextjs-notion-starter-kit.git
synced 2026-05-13 23:16:47 +00:00
feat: refactoring config to site.config.js
This commit is contained in:
104
lib/config.ts
104
lib/config.ts
@@ -1,43 +1,65 @@
|
||||
/**
|
||||
* Site-wide app configuration.
|
||||
*
|
||||
* @see env.ts for config relating to third-party dependencies.
|
||||
*/
|
||||
|
||||
import { getEnv } from './get-env'
|
||||
import { getSiteConfig, getEnv } from './get-config-value'
|
||||
|
||||
// where it all starts -- the site's root Notion page
|
||||
export const rootNotionPageId = '78fc5a4b88d74b0e824e29407e9f1ec1'
|
||||
export const rootNotionPageId: string = getSiteConfig('rootNotionPageId')
|
||||
|
||||
// general site config
|
||||
export const siteName = 'Transitive Bullshit'
|
||||
export const siteAuthor = 'Travis Fischer'
|
||||
export const siteAuthorTwitter = 'transitive_bs'
|
||||
export const siteDomain = 'transitivebullsh.it'
|
||||
export const siteDescription =
|
||||
'Personal site of Travis Fischer aka Transitive Bullshit'
|
||||
export const siteFavicon = `https://${siteDomain}/favicon.png`
|
||||
export const socialImageTitle = 'Transitive Bullshit'
|
||||
export const socialImageSubtitle = 'Hello World! 👋'
|
||||
export const name: string = getSiteConfig('name')
|
||||
export const author: string = getSiteConfig('author')
|
||||
export const domain: string = getSiteConfig('domain')
|
||||
export const description: string = getSiteConfig('description', 'Notion Blog')
|
||||
|
||||
// social accounts
|
||||
export const twitter: string | null = getSiteConfig('twitter', null)
|
||||
export const github: string | null = getSiteConfig('github', null)
|
||||
export const linkedin: string | null = getSiteConfig('linkedin', null)
|
||||
|
||||
export const socialImageTitle: string | null = getSiteConfig(
|
||||
'socialImageTitle',
|
||||
null
|
||||
)
|
||||
export const socialImageSubtitle: string | null = getSiteConfig(
|
||||
'socialImageSubtitle',
|
||||
null
|
||||
)
|
||||
|
||||
// default notion values for site-wide consistency (optional; may be overridden on a per-page basis)
|
||||
export const defaultPageIcon =
|
||||
'https://ssfy.io/https%3A%2F%2Fwww.notion.so%2Fimage%2Fhttps%253A%252F%252Fs3-us-west-2.amazonaws.com%252Fsecure.notion-static.com%252F797768e4-f24a-4e65-bd4a-b622ae9671dc%252Fprofile-2020-280w-circle.png%3Ftable%3Dblock%26id%3D78fc5a4b-88d7-4b0e-824e-29407e9f1ec1%26cache%3Dv2'
|
||||
export const defaultPageCover =
|
||||
'https://ssfy.io/https%3A%2F%2Fwww.notion.so%2Fimage%2Fhttps%253A%252F%252Fs3-us-west-2.amazonaws.com%252Fsecure.notion-static.com%252F9fc5ecae-2b4b-4e73-b0d4-918c829ba69f%252FIMG_0259-opt.jpg%3Ftable%3Dblock%26id%3D78fc5a4b-88d7-4b0e-824e-29407e9f1ec1%26cache%3Dv2'
|
||||
export const defaultPageCoverPosition = 0.1862
|
||||
export const defaultPageIcon: string | null = getSiteConfig(
|
||||
'defaultPageIcon',
|
||||
null
|
||||
)
|
||||
export const defaultPageCover: string | null = getSiteConfig(
|
||||
'defaultPageCover',
|
||||
null
|
||||
)
|
||||
export const defaultPageCoverPosition: number = getSiteConfig(
|
||||
'defaultPageCoverPosition',
|
||||
0.5
|
||||
)
|
||||
|
||||
// image CDN host to proxy all image requests through
|
||||
export const imageCDNHost: string | null = getSiteConfig('imageCDNHost', null)
|
||||
|
||||
// whether or not to enable support for LQIP preview images
|
||||
// (requires a Google Firebase collection)
|
||||
export const isPreviewImageSupportEnabled = true
|
||||
export const isPreviewImageSupportEnabled: boolean = getSiteConfig(
|
||||
'isPreviewImageSupportEnabled',
|
||||
false
|
||||
)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
export const isDev =
|
||||
process.env.NODE_ENV === 'development' || !process.env.NODE_ENV
|
||||
|
||||
export const isServer = typeof window === 'undefined'
|
||||
|
||||
export const port = getEnv('PORT', '3000')
|
||||
export const host = isDev ? `http://localhost:${port}` : `https://${siteDomain}`
|
||||
export const host = isDev ? `http://localhost:${port}` : `https://${domain}`
|
||||
|
||||
export const apiBaseUrl = `${host}/api`
|
||||
|
||||
@@ -47,6 +69,8 @@ export const api = {
|
||||
renderSocialImage: (pageId) => `${apiBaseUrl}/render-social-image/${pageId}`
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
export const fathomId = isDev ? null : getEnv('FATHOM_ID', null)
|
||||
|
||||
export const fathomConfig = fathomId
|
||||
@@ -54,3 +78,43 @@ export const fathomConfig = fathomId
|
||||
excludedDomains: ['localhost', 'localhost:3000']
|
||||
}
|
||||
: undefined
|
||||
|
||||
const defaultEnvValueForPreviewImageSupport =
|
||||
isPreviewImageSupportEnabled && isServer ? undefined : null
|
||||
|
||||
export const googleProjectId = getEnv(
|
||||
'GCLOUD_PROJECT',
|
||||
defaultEnvValueForPreviewImageSupport
|
||||
)
|
||||
|
||||
export const googleApplicationCredentials = getGoogleApplicationCredentials()
|
||||
|
||||
export const firebaseCollectionImages = getEnv(
|
||||
'FIREBASE_COLLECTION_IMAGES',
|
||||
defaultEnvValueForPreviewImageSupport
|
||||
)
|
||||
|
||||
// this hack is necessary because vercel doesn't support secret files so we need to encode our google
|
||||
// credentials a base64-encoded string of the JSON-ified content
|
||||
function getGoogleApplicationCredentials() {
|
||||
if (!isPreviewImageSupportEnabled || !isServer) {
|
||||
return null
|
||||
}
|
||||
|
||||
try {
|
||||
const googleApplicationCredentialsBase64 = getEnv(
|
||||
'GOOGLE_APPLICATION_CREDENTIALS',
|
||||
defaultEnvValueForPreviewImageSupport
|
||||
)
|
||||
|
||||
return JSON.parse(
|
||||
Buffer.from(googleApplicationCredentialsBase64, 'base64').toString()
|
||||
)
|
||||
} catch (err) {
|
||||
console.error(
|
||||
'Firebase config error: invalid "GOOGLE_APPLICATION_CREDENTIALS" should be base64-encoded JSON\n'
|
||||
)
|
||||
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
15
lib/db.ts
15
lib/db.ts
@@ -1,18 +1,17 @@
|
||||
import * as firestore from '@google-cloud/firestore'
|
||||
import * as types from './types'
|
||||
import * as env from './env'
|
||||
import { isPreviewImageSupportEnabled } from './config'
|
||||
import * as config from './config'
|
||||
|
||||
export let db = null
|
||||
export let images = null
|
||||
export let db: firestore.Firestore = null
|
||||
export let images: firestore.CollectionReference = null
|
||||
|
||||
if (isPreviewImageSupportEnabled) {
|
||||
if (config.isPreviewImageSupportEnabled) {
|
||||
db = new firestore.Firestore({
|
||||
projectId: env.googleProjectId,
|
||||
credentials: env.googleApplicationCredentials
|
||||
projectId: config.googleProjectId,
|
||||
credentials: config.googleApplicationCredentials
|
||||
})
|
||||
|
||||
images = db.collection(env.firebaseCollectionImages)
|
||||
images = db.collection(config.firebaseCollectionImages)
|
||||
}
|
||||
|
||||
async function get<T extends types.Model>(
|
||||
|
||||
54
lib/env.ts
54
lib/env.ts
@@ -1,54 +0,0 @@
|
||||
/**
|
||||
* Config for third-party dependencies.
|
||||
*
|
||||
* - Google Cloud (Firebase) - for simple database functionality.
|
||||
* - Fathom - simple analytics.
|
||||
*
|
||||
* @see config.ts for primary configuration.
|
||||
*/
|
||||
|
||||
import { getEnv } from './get-env'
|
||||
import { isPreviewImageSupportEnabled } from './config'
|
||||
|
||||
export { isPreviewImageSupportEnabled }
|
||||
|
||||
const defaultEnvValueForPreviewImageSupport = isPreviewImageSupportEnabled
|
||||
? undefined
|
||||
: null
|
||||
|
||||
export const googleProjectId = getEnv(
|
||||
'GCLOUD_PROJECT',
|
||||
defaultEnvValueForPreviewImageSupport
|
||||
)
|
||||
|
||||
export const googleApplicationCredentials = getGoogleApplicationCredentials()
|
||||
|
||||
export const firebaseCollectionImages = getEnv(
|
||||
'FIREBASE_COLLECTION_IMAGES',
|
||||
defaultEnvValueForPreviewImageSupport
|
||||
)
|
||||
|
||||
// this hack is necessary because vercel doesn't support secret files so we need to encode our google
|
||||
// credentials a base64-encoded string of the JSON-ified content
|
||||
function getGoogleApplicationCredentials() {
|
||||
if (!isPreviewImageSupportEnabled) {
|
||||
return null
|
||||
}
|
||||
|
||||
try {
|
||||
const googleApplicationCredentialsBase64 = getEnv(
|
||||
'GOOGLE_APPLICATION_CREDENTIALS',
|
||||
defaultEnvValueForPreviewImageSupport
|
||||
)
|
||||
|
||||
return JSON.parse(
|
||||
Buffer.from(googleApplicationCredentialsBase64, 'base64').toString()
|
||||
)
|
||||
} catch (err) {
|
||||
console.error(
|
||||
'Firebase config error: invalid "GOOGLE_APPLICATION_CREDENTIALS" should be base64-encoded JSON\n'
|
||||
)
|
||||
|
||||
throw err
|
||||
}
|
||||
}
|
||||
37
lib/get-config-value.ts
Normal file
37
lib/get-config-value.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import siteConfig from '../site.config'
|
||||
|
||||
if (!siteConfig) {
|
||||
throw new Error(`Config error: invalid site.config.js`)
|
||||
}
|
||||
|
||||
export function getSiteConfig<T>(key: string, defaultValue?: T): T {
|
||||
const value = siteConfig[key]
|
||||
|
||||
if (value !== undefined) {
|
||||
return value
|
||||
}
|
||||
|
||||
if (defaultValue !== undefined) {
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
throw new Error(`Config error: missing required site config value "${key}"`)
|
||||
}
|
||||
|
||||
export function getEnv(
|
||||
key: string,
|
||||
defaultValue?: string,
|
||||
env = process.env
|
||||
): string {
|
||||
const value = env[key]
|
||||
|
||||
if (value !== undefined) {
|
||||
return value
|
||||
}
|
||||
|
||||
if (defaultValue !== undefined) {
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
throw new Error(`Config error: missing required env variable "${key}"`)
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
export function getEnv(
|
||||
key: string,
|
||||
defaultValue?: string,
|
||||
env = process.env
|
||||
): string {
|
||||
const value = env[key]
|
||||
|
||||
if (value !== undefined) {
|
||||
return value
|
||||
}
|
||||
|
||||
if (defaultValue !== undefined) {
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
throw new Error(`Config error: missing required env var "${key}"`)
|
||||
}
|
||||
@@ -6,8 +6,8 @@ export const getSiteForDomain = async (
|
||||
): Promise<types.Site | null> => {
|
||||
return {
|
||||
domain,
|
||||
name: config.siteName,
|
||||
name: config.name,
|
||||
rootNotionPageId: config.rootNotionPageId,
|
||||
description: config.siteDescription
|
||||
description: config.description
|
||||
} as types.Site
|
||||
}
|
||||
|
||||
@@ -3,5 +3,5 @@ import * as config from './config'
|
||||
import * as types from './types'
|
||||
|
||||
export async function getSites(): Promise<types.Site[]> {
|
||||
return [await getSiteForDomain(config.siteDomain)]
|
||||
return [await getSiteForDomain(config.domain)]
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Block } from 'notion-types'
|
||||
|
||||
const imageCDNHost = 'https://ssfy.io'
|
||||
import { imageCDNHost } from './config'
|
||||
|
||||
export const mapNotionImageUrl = (url: string, block: Block) => {
|
||||
if (!url) {
|
||||
@@ -11,7 +10,7 @@ export const mapNotionImageUrl = (url: string, block: Block) => {
|
||||
return url
|
||||
}
|
||||
|
||||
if (url.startsWith(imageCDNHost)) {
|
||||
if (imageCDNHost && url.startsWith(imageCDNHost)) {
|
||||
return url
|
||||
}
|
||||
|
||||
@@ -48,6 +47,10 @@ export const mapImageUrl = (imageUrl: string) => {
|
||||
return imageUrl
|
||||
}
|
||||
|
||||
// Our proxy uses Cloudflare's global CDN to cache these image assets
|
||||
return `${imageCDNHost}/${encodeURIComponent(imageUrl)}`
|
||||
if (imageCDNHost) {
|
||||
// Our proxy uses Cloudflare's global CDN to cache these image assets
|
||||
return `${imageCDNHost}/${encodeURIComponent(imageUrl)}`
|
||||
} else {
|
||||
return imageUrl
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,8 +16,8 @@ export const oembed = async ({
|
||||
// TODO: handle pages with no pageId via domain
|
||||
const pageId = parsePageId(url)
|
||||
|
||||
let title = config.siteName
|
||||
let authorName = config.siteAuthor
|
||||
let title = config.name
|
||||
let authorName = config.author
|
||||
|
||||
try {
|
||||
const page = await getPage(pageId)
|
||||
@@ -50,7 +50,7 @@ export const oembed = async ({
|
||||
return {
|
||||
version: '1.0',
|
||||
type: 'rich',
|
||||
provider_name: config.siteName,
|
||||
provider_name: config.author,
|
||||
provider_url: config.host,
|
||||
title,
|
||||
author_name: authorName,
|
||||
|
||||
Reference in New Issue
Block a user