From b60fbcc15c38c0ed47d3fc96ea31e0f9a25abbea Mon Sep 17 00:00:00 2001 From: Jake Jarvis Date: Sun, 13 Apr 2025 16:28:00 -0400 Subject: [PATCH] clean up remaining NEXT_PUBLIC_ environment variables --- .env.example | 4 +++ app/birthday/page.tsx | 8 ++--- app/hillary/page.tsx | 8 ++--- app/layout.tsx | 19 +++++------ app/leo/page.tsx | 8 ++--- app/manifest.ts | 4 +-- app/notes/[slug]/counter.tsx | 4 +-- app/notes/[slug]/page.tsx | 45 +++++++++++++------------- app/projects/page.tsx | 9 +++--- app/robots.ts | 4 +-- app/sitemap.ts | 8 ++--- components/Comments/Comments.tsx | 3 +- components/Footer/Footer.tsx | 6 ++-- components/Time/Time.tsx | 6 ++-- lib/config/constants.ts | 19 ----------- lib/config/index.ts | 1 - lib/env.ts | 54 ++++++++++++++++++++++++++++++++ lib/helpers/build-feed.ts | 18 +++++------ lib/helpers/metadata.ts | 6 ++-- lib/helpers/posts.ts | 5 +-- next.config.ts | 15 --------- 21 files changed, 137 insertions(+), 117 deletions(-) diff --git a/.env.example b/.env.example index efe4fc9b..93a9058f 100644 --- a/.env.example +++ b/.env.example @@ -10,7 +10,11 @@ RESEND_API_KEY= RESEND_FROM_EMAIL= RESEND_TO_EMAIL= TURNSTILE_SECRET_KEY= +NEXT_PUBLIC_BASE_URL= NEXT_PUBLIC_GISCUS_CATEGORY_ID= NEXT_PUBLIC_GISCUS_REPO_ID= +NEXT_PUBLIC_GITHUB_REPO= NEXT_PUBLIC_ONION_DOMAIN= +NEXT_PUBLIC_SITE_LOCALE= +NEXT_PUBLIC_SITE_TZ= NEXT_PUBLIC_TURNSTILE_SITE_KEY= diff --git a/app/birthday/page.tsx b/app/birthday/page.tsx index f0e14477..1bef9811 100644 --- a/app/birthday/page.tsx +++ b/app/birthday/page.tsx @@ -1,8 +1,8 @@ +import { env } from "../../lib/env"; import { JsonLd } from "react-schemaorg"; import PageTitle from "../../components/PageTitle"; import Video from "../../components/Video"; import { addMetadata } from "../../lib/helpers/metadata"; -import { BASE_URL } from "../../lib/config/constants"; import type { VideoObject } from "schema-dts"; import mp4 from "./birthday.mp4"; @@ -26,9 +26,9 @@ const Page = () => { "@type": "VideoObject", name: metadata.title as string, description: metadata.description as string, - contentUrl: `${BASE_URL}${webm}`, - thumbnailUrl: `${BASE_URL}${thumbnail.src}`, - embedUrl: `${BASE_URL}/birthday`, + contentUrl: `${env.NEXT_PUBLIC_BASE_URL}${webm}`, + thumbnailUrl: `${env.NEXT_PUBLIC_BASE_URL}${thumbnail.src}`, + embedUrl: `${env.NEXT_PUBLIC_BASE_URL}/birthday`, uploadDate: "1996-02-06T00:00:00Z", duration: "PT6M10S", }} diff --git a/app/hillary/page.tsx b/app/hillary/page.tsx index f222be7e..1564b70b 100644 --- a/app/hillary/page.tsx +++ b/app/hillary/page.tsx @@ -1,9 +1,9 @@ +import { env } from "../../lib/env"; import { JsonLd } from "react-schemaorg"; import PageTitle from "../../components/PageTitle"; import Link from "../../components/Link"; import Video from "../../components/Video"; import { addMetadata } from "../../lib/helpers/metadata"; -import { BASE_URL } from "../../lib/config/constants"; import type { VideoObject } from "schema-dts"; import webm from "./convention.webm"; @@ -28,9 +28,9 @@ const Page = () => { "@type": "VideoObject", name: metadata.title as string, description: metadata.description as string, - contentUrl: `${BASE_URL}${webm}`, - thumbnailUrl: `${BASE_URL}${thumbnail.src}`, - embedUrl: `${BASE_URL}/hillary`, + contentUrl: `${env.NEXT_PUBLIC_BASE_URL}${webm}`, + thumbnailUrl: `${env.NEXT_PUBLIC_BASE_URL}${thumbnail.src}`, + embedUrl: `${env.NEXT_PUBLIC_BASE_URL}/hillary`, uploadDate: "2016-07-25T00:00:00Z", duration: "PT1M51S", }} diff --git a/app/layout.tsx b/app/layout.tsx index 4a879b95..3061e5fe 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,3 +1,4 @@ +import { env } from "../lib/env"; import { JsonLd } from "react-schemaorg"; import { Analytics } from "@vercel/analytics/next"; import clsx from "clsx"; @@ -7,7 +8,7 @@ import Footer from "../components/Footer"; import { SkipNavLink, SkipNavTarget } from "../components/SkipNav"; import { defaultMetadata } from "../lib/helpers/metadata"; import * as config from "../lib/config"; -import { BASE_URL, MAX_WIDTH, SITE_LOCALE } from "../lib/config/constants"; +import { MAX_WIDTH } from "../lib/config/constants"; import type { Metadata } from "next"; import type { Person, WebSite } from "schema-dts"; @@ -21,7 +22,7 @@ export const metadata: Metadata = defaultMetadata; const RootLayout = ({ children }: Readonly<{ children: React.ReactNode }>) => { return ( - + @@ -29,12 +30,12 @@ const RootLayout = ({ children }: Readonly<{ children: React.ReactNode }>) => { item={{ "@context": "https://schema.org", "@type": "Person", - "@id": `${BASE_URL}/#person`, + "@id": `${env.NEXT_PUBLIC_BASE_URL}/#person`, name: config.authorName, - url: BASE_URL, - image: [`${BASE_URL}/opengraph-image.jpg`], + url: env.NEXT_PUBLIC_BASE_URL, + image: [`${env.NEXT_PUBLIC_BASE_URL}/opengraph-image.jpg`], sameAs: [ - `${BASE_URL}`, + env.NEXT_PUBLIC_BASE_URL!, `https://${config.authorSocial?.mastodon}`, `https://github.com/${config.authorSocial?.github}`, `https://bsky.app/profile/${config.authorSocial?.bluesky}`, @@ -51,12 +52,12 @@ const RootLayout = ({ children }: Readonly<{ children: React.ReactNode }>) => { item={{ "@context": "https://schema.org", "@type": "WebSite", - "@id": `${BASE_URL}/#website`, + "@id": `${env.NEXT_PUBLIC_BASE_URL}/#website`, name: config.siteName, - url: BASE_URL, + url: env.NEXT_PUBLIC_BASE_URL, author: config.authorName, description: config.description, - inLanguage: SITE_LOCALE, + inLanguage: env.NEXT_PUBLIC_SITE_LOCALE, license: config.licenseUrl, }} /> diff --git a/app/leo/page.tsx b/app/leo/page.tsx index 3be07b98..ec8c9013 100644 --- a/app/leo/page.tsx +++ b/app/leo/page.tsx @@ -1,9 +1,9 @@ +import { env } from "../../lib/env"; import { JsonLd } from "react-schemaorg"; import PageTitle from "../../components/PageTitle"; import Link from "../../components/Link"; import Video from "../../components/Video"; import { addMetadata } from "../../lib/helpers/metadata"; -import { BASE_URL } from "../../lib/config/constants"; import type { VideoObject } from "schema-dts"; import mp4 from "./leo.mp4"; @@ -28,9 +28,9 @@ const Page = () => { "@type": "VideoObject", name: metadata.title as string, description: metadata.description as string, - contentUrl: `${BASE_URL}${webm}`, - thumbnailUrl: `${BASE_URL}${thumbnail.src}`, - embedUrl: `${BASE_URL}/leo`, + contentUrl: `${env.NEXT_PUBLIC_BASE_URL}${webm}`, + thumbnailUrl: `${env.NEXT_PUBLIC_BASE_URL}${thumbnail.src}`, + embedUrl: `${env.NEXT_PUBLIC_BASE_URL}/leo`, uploadDate: "2007-05-10T00:00:00Z", duration: "PT1M48S", }} diff --git a/app/manifest.ts b/app/manifest.ts index 4f8e1eba..8cfab239 100644 --- a/app/manifest.ts +++ b/app/manifest.ts @@ -1,5 +1,5 @@ +import { env } from "../lib/env"; import * as config from "../lib/config"; -import { SITE_LOCALE } from "../lib/config/constants"; import type { MetadataRoute } from "next"; const manifest = (): MetadataRoute.Manifest => { @@ -8,7 +8,7 @@ const manifest = (): MetadataRoute.Manifest => { // eslint-disable-next-line camelcase short_name: config.siteName, description: config.description, - lang: SITE_LOCALE, + lang: env.NEXT_PUBLIC_SITE_LOCALE, icons: [ { src: "/icon.png", diff --git a/app/notes/[slug]/counter.tsx b/app/notes/[slug]/counter.tsx index 42c057aa..becf840f 100644 --- a/app/notes/[slug]/counter.tsx +++ b/app/notes/[slug]/counter.tsx @@ -1,7 +1,7 @@ +import { env } from "../../../lib/env"; import { connection } from "next/server"; import CountUp from "../../../components/CountUp"; import redis from "../../../lib/redis"; -import { SITE_LOCALE } from "../../../lib/config/constants"; const HitCounter = async ({ slug }: { slug: string }) => { await connection(); @@ -16,7 +16,7 @@ const HitCounter = async ({ slug }: { slug: string }) => { // we have data! return ( - + ); diff --git a/app/notes/[slug]/page.tsx b/app/notes/[slug]/page.tsx index 48c711e2..8288d20d 100644 --- a/app/notes/[slug]/page.tsx +++ b/app/notes/[slug]/page.tsx @@ -10,7 +10,7 @@ import HitCounter from "./counter"; import { getSlugs, getFrontMatter } from "../../../lib/helpers/posts"; import { addMetadata } from "../../../lib/helpers/metadata"; import * as config from "../../../lib/config"; -import { BASE_URL, POSTS_DIR, SITE_LOCALE } from "../../../lib/config/constants"; +import { POSTS_DIR } from "../../../lib/config/constants"; import { size as ogImageSize } from "./opengraph-image"; import type { Metadata } from "next"; import type { BlogPosting } from "schema-dts"; @@ -72,18 +72,18 @@ const Page = async ({ params }: { params: Promise<{ slug: string }> }) => { url: frontmatter!.permalink, image: { "@type": "ImageObject", - contentUrl: `${BASE_URL}/${POSTS_DIR}/${frontmatter!.slug}/opengraph-image`, + contentUrl: `${env.NEXT_PUBLIC_BASE_URL}/${POSTS_DIR}/${frontmatter!.slug}/opengraph-image`, width: `${ogImageSize.width}`, height: `${ogImageSize.height}`, }, keywords: frontmatter!.tags?.join(", "), datePublished: frontmatter!.date, dateModified: frontmatter!.date, - inLanguage: SITE_LOCALE, + inLanguage: env.NEXT_PUBLIC_SITE_LOCALE, license: config.licenseUrl, author: { // defined in app/layout.tsx - "@id": `${BASE_URL}/#person`, + "@id": `${env.NEXT_PUBLIC_BASE_URL}/#person`, }, }} /> @@ -111,7 +111,7 @@ const Page = async ({ params }: { params: Promise<{ slug: string }> }) => {
}) => {
- {/* only count hits on production site */} - {env.VERCEL_ENV === "production" ? ( -
+ + 0} > - - 0} - > - - -
- ) : null} + + +

diff --git a/app/projects/page.tsx b/app/projects/page.tsx index 015f61e5..bb40e18f 100644 --- a/app/projects/page.tsx +++ b/app/projects/page.tsx @@ -7,7 +7,6 @@ import Link from "../../components/Link"; import RelativeTime from "../../components/RelativeTime"; import { addMetadata } from "../../lib/helpers/metadata"; import * as config from "../../lib/config"; -import { SITE_LOCALE } from "../../lib/config/constants"; import type { User } from "@octokit/graphql-schema"; import styles from "./page.module.css"; @@ -121,12 +120,12 @@ const Page = async () => {
- {Intl.NumberFormat(SITE_LOCALE || "en-US").format(repo!.stargazerCount)} + {Intl.NumberFormat(env.NEXT_PUBLIC_SITE_LOCALE).format(repo!.stargazerCount)}
)} @@ -135,12 +134,12 @@ const Page = async () => {
- {Intl.NumberFormat(SITE_LOCALE || "en-US").format(repo!.forkCount)} + {Intl.NumberFormat(env.NEXT_PUBLIC_SITE_LOCALE).format(repo!.forkCount)}
)} diff --git a/app/robots.ts b/app/robots.ts index d9ab1771..209036bf 100644 --- a/app/robots.ts +++ b/app/robots.ts @@ -1,4 +1,4 @@ -import { BASE_URL } from "../lib/config/constants"; +import { env } from "../lib/env"; import type { MetadataRoute } from "next"; const robots = (): MetadataRoute.Robots => ({ @@ -8,7 +8,7 @@ const robots = (): MetadataRoute.Robots => ({ disallow: ["/api/", "/404", "/500"], }, ], - sitemap: `${BASE_URL}/sitemap.xml`, + sitemap: `${env.NEXT_PUBLIC_BASE_URL}/sitemap.xml`, }); export default robots; diff --git a/app/sitemap.ts b/app/sitemap.ts index f30bd822..1123535c 100644 --- a/app/sitemap.ts +++ b/app/sitemap.ts @@ -1,7 +1,7 @@ +import { env } from "../lib/env"; import path from "path"; import glob from "fast-glob"; import { getFrontMatter } from "../lib/helpers/posts"; -import { BASE_URL, RELEASE_TIMESTAMP } from "../lib/config/constants"; import type { MetadataRoute } from "next"; const sitemap = async (): Promise => { @@ -9,9 +9,9 @@ const sitemap = async (): Promise => { const routes: MetadataRoute.Sitemap = [ { // homepage - url: `${BASE_URL}`, + url: `${env.NEXT_PUBLIC_BASE_URL}`, priority: 1.0, - lastModified: new Date(RELEASE_TIMESTAMP), // timestamp frozen when a new build is deployed + lastModified: new Date(), }, ]; @@ -30,7 +30,7 @@ const sitemap = async (): Promise => { ).forEach((route) => { routes.push({ // remove matching page.(tsx|mdx) file and make all URLs absolute - url: `${BASE_URL}/${route.replace(/\/page\.(tsx|mdx)$/, "")}`, + url: `${env.NEXT_PUBLIC_BASE_URL}/${route.replace(/\/page\.(tsx|mdx)$/, "")}`, }); }); diff --git a/components/Comments/Comments.tsx b/components/Comments/Comments.tsx index 7b67e95a..feaf921d 100644 --- a/components/Comments/Comments.tsx +++ b/components/Comments/Comments.tsx @@ -2,7 +2,6 @@ import { env } from "../../lib/env"; import Giscus from "@giscus/react"; -import * as config from "../../lib/config"; import type { GiscusProps } from "@giscus/react"; export type CommentsProps = { @@ -21,7 +20,7 @@ const Comments = ({ title }: CommentsProps) => { return ( { {config.copyrightYearStart} {" "} - – {new Date(RELEASE_TIMESTAMP).getUTCFullYear()}. + – {new Date().getUTCFullYear()}.
@@ -53,7 +53,7 @@ const Footer = ({ className, ...rest }: FooterProps) => { .{" "} & { @@ -14,10 +14,10 @@ const Time = ({ date, format: formatStr = "PPpp", ...rest }: TimeProps) => { return ( ); }; diff --git a/lib/config/constants.ts b/lib/config/constants.ts index cb02c029..7c3e1cb7 100644 --- a/lib/config/constants.ts +++ b/lib/config/constants.ts @@ -1,16 +1,3 @@ -/** - * Locale code to define the site's language in ISO-639 format. Defaults to `en-US`. - * @see https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes#Table - */ -export const SITE_LOCALE = "en-US"; - -/** - * Consistent timezone for the site. Doesn't really matter what it is, as long as it's the same everywhere to avoid - * hydration complaints. - * @see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List - */ -export const SITE_TZ = "America/New_York"; - /** Path to directory with .mdx files, relative to project root. */ export const POSTS_DIR = "notes"; @@ -22,9 +9,3 @@ export const AVATAR_PATH = "app/avatar.jpg"; /** Maximum width of content wrapper (e.g. for images) in pixels. */ export const MAX_WIDTH = 865; - -/** Chooses the most appropriate URL for the current deployment. Defined in [`next.config.ts`](../../next.config.ts). */ -export const BASE_URL = process.env.NEXT_PUBLIC_BASE_URL!; - -/** Freezes time at build. Defined in [`next.config.ts`](../../next.config.ts). */ -export const RELEASE_TIMESTAMP = process.env.NEXT_PUBLIC_RELEASE_TIMESTAMP!; diff --git a/lib/config/index.ts b/lib/config/index.ts index e48bf4ea..3cda4dfd 100644 --- a/lib/config/index.ts +++ b/lib/config/index.ts @@ -7,7 +7,6 @@ export const license = "Creative Commons Attribution 4.0 International"; export const licenseAbbr = "CC-BY-4.0"; export const licenseUrl = "https://creativecommons.org/licenses/by/4.0/"; export const copyrightYearStart = 2001; -export const githubRepo = "jakejarvis/jarv.is"; // Me info export const authorName = "Jake Jarvis"; diff --git a/lib/env.ts b/lib/env.ts index d72336c1..be175576 100644 --- a/lib/env.ts +++ b/lib/env.ts @@ -64,6 +64,13 @@ export const env = createEnv({ TURNSTILE_SECRET_KEY: v.optional(v.string(), "1x0000000000000000000000000000000AA"), }, client: { + /** + * Optional. Overrides the most appropriate default URL for the current deployment. + * + * @see https://nextjs.org/docs/app/api-reference/functions/generate-metadata#default-value + */ + NEXT_PUBLIC_BASE_URL: v.optional(v.pipe(v.string(), v.url())), + /** * Optional. Enables comments on blog posts via GitHub discussions. * @@ -77,6 +84,11 @@ export const env = createEnv({ */ NEXT_PUBLIC_GISCUS_REPO_ID: v.optional(v.string()), + /** + * Required. GitHub repository for the site in the format of `{username}/{repo}`. + */ + NEXT_PUBLIC_GITHUB_REPO: v.string(), + /** * Optional. Sets an `Onion-Location` header in responses to advertise a URL for the same page but hosted on a * hidden service on the Tor network. Browsers like Brave and Tor Browser will automatically pick this up and offer @@ -86,6 +98,21 @@ export const env = createEnv({ */ NEXT_PUBLIC_ONION_DOMAIN: v.optional(v.pipe(v.string(), v.endsWith(".onion"))), + /** + * Optional. Locale code to define the site's language in ISO-639 format. Defaults to `en-US`. + * + * @see https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes#Table + */ + NEXT_PUBLIC_SITE_LOCALE: v.optional(v.string(), "en-US"), + + /** + * Optional. Consistent timezone for the site. Doesn't really matter what it is, as long as it's the same everywhere + * to avoid hydration complaints. + * + * @see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List + */ + NEXT_PUBLIC_SITE_TZ: v.optional(v.string(), "America/New_York"), + /** * Required. Site key must be prefixed with NEXT_PUBLIC_ since it is used to embed the captcha widget. Falls back to * testing keys if not set or in dev environment. @@ -95,9 +122,36 @@ export const env = createEnv({ NEXT_PUBLIC_TURNSTILE_SITE_KEY: v.optional(v.string(), "XXXX.DUMMY.TOKEN.XXXX"), }, experimental__runtimeEnv: { + NEXT_PUBLIC_BASE_URL: + process.env.NEXT_PUBLIC_BASE_URL || + // Vercel: https://vercel.com/docs/environment-variables/system-environment-variables + (process.env.VERCEL + ? process.env.VERCEL_ENV === "production" && process.env.VERCEL_PROJECT_PRODUCTION_URL + ? `https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}` + : process.env.VERCEL_ENV === "preview" && process.env.VERCEL_BRANCH_URL + ? `https://${process.env.VERCEL_BRANCH_URL}` + : process.env.VERCEL_URL + ? `https://${process.env.VERCEL_URL}` + : undefined + : undefined) || + // Netlify: https://docs.netlify.com/configure-builds/environment-variables/#read-only-variables + (process.env.NETLIFY + ? process.env.CONTEXT === "production" && process.env.URL + ? `${process.env.URL}` + : process.env.DEPLOY_PRIME_URL + ? `${process.env.DEPLOY_PRIME_URL}` + : process.env.DEPLOY_URL + ? `${process.env.DEPLOY_URL}` + : undefined + : undefined) || + // next dev + `http://localhost:${process.env.PORT || 3000}`, NEXT_PUBLIC_GISCUS_CATEGORY_ID: process.env.NEXT_PUBLIC_GISCUS_CATEGORY_ID, NEXT_PUBLIC_GISCUS_REPO_ID: process.env.NEXT_PUBLIC_GISCUS_REPO_ID, + NEXT_PUBLIC_GITHUB_REPO: process.env.NEXT_PUBLIC_GITHUB_REPO, NEXT_PUBLIC_ONION_DOMAIN: process.env.NEXT_PUBLIC_ONION_DOMAIN, + NEXT_PUBLIC_SITE_LOCALE: process.env.NEXT_PUBLIC_SITE_LOCALE, + NEXT_PUBLIC_SITE_TZ: process.env.NEXT_PUBLIC_SITE_TZ, NEXT_PUBLIC_TURNSTILE_SITE_KEY: process.env.NEXT_PUBLIC_TURNSTILE_SITE_KEY, }, emptyStringAsUndefined: true, diff --git a/lib/helpers/build-feed.ts b/lib/helpers/build-feed.ts index 033273a7..12ddbb78 100644 --- a/lib/helpers/build-feed.ts +++ b/lib/helpers/build-feed.ts @@ -1,7 +1,7 @@ +import { env } from "../../lib/env"; import { Feed } from "feed"; import { getFrontMatter, getContent } from "./posts"; import * as config from "../config"; -import { BASE_URL, RELEASE_TIMESTAMP } from "../config/constants"; import type { Item as FeedItem } from "feed"; import ogImage from "../../app/opengraph-image.jpg"; @@ -12,20 +12,20 @@ import ogImage from "../../app/opengraph-image.jpg"; */ export const buildFeed = async (): Promise => { const feed = new Feed({ - id: `${BASE_URL}`, - link: `${BASE_URL}`, + id: `${env.NEXT_PUBLIC_BASE_URL}`, + link: `${env.NEXT_PUBLIC_BASE_URL}`, title: config.siteName, description: config.description, copyright: config.licenseUrl, - updated: new Date(RELEASE_TIMESTAMP), - image: `${BASE_URL}${ogImage.src}`, + updated: new Date(), + image: `${env.NEXT_PUBLIC_BASE_URL}${ogImage.src}`, feedLinks: { - rss: `${BASE_URL}/feed.xml`, - atom: `${BASE_URL}/feed.atom`, + rss: `${env.NEXT_PUBLIC_BASE_URL}/feed.xml`, + atom: `${env.NEXT_PUBLIC_BASE_URL}/feed.atom`, }, author: { name: config.authorName, - link: BASE_URL, + link: env.NEXT_PUBLIC_BASE_URL, email: config.authorEmail, }, }); @@ -41,7 +41,7 @@ export const buildFeed = async (): Promise => { author: [ { name: config.authorName, - link: `${BASE_URL}`, + link: `${env.NEXT_PUBLIC_BASE_URL}`, }, ], date: new Date(post.date), diff --git a/lib/helpers/metadata.ts b/lib/helpers/metadata.ts index 43033d2d..a0d71096 100644 --- a/lib/helpers/metadata.ts +++ b/lib/helpers/metadata.ts @@ -1,9 +1,9 @@ +import { env } from "../env"; import * as config from "../config"; -import { BASE_URL, SITE_LOCALE } from "../config/constants"; import type { Metadata } from "next"; export const defaultMetadata: Metadata = { - metadataBase: new URL(BASE_URL), + metadataBase: env.NEXT_PUBLIC_BASE_URL ? new URL(env.NEXT_PUBLIC_BASE_URL) : undefined, title: { template: `%s – ${config.siteName}`, default: `${config.siteName} – ${config.tagline}`, @@ -16,7 +16,7 @@ export const defaultMetadata: Metadata = { default: `${config.siteName} – ${config.tagline}`, }, url: "/", - locale: SITE_LOCALE?.replace("-", "_"), + locale: env.NEXT_PUBLIC_SITE_LOCALE.replace("-", "_"), type: "website", }, twitter: { diff --git a/lib/helpers/posts.ts b/lib/helpers/posts.ts index 7eccb521..c0906f20 100644 --- a/lib/helpers/posts.ts +++ b/lib/helpers/posts.ts @@ -1,10 +1,11 @@ +import { env } from "../../lib/env"; import path from "path"; import fs from "fs/promises"; import glob from "fast-glob"; import { unified } from "unified"; import { remarkHtml, remarkParse, remarkSmartypants, remarkFrontmatter } from "./remark-rehype-plugins"; import { decode } from "html-entities"; -import { BASE_URL, POSTS_DIR } from "../config/constants"; +import { POSTS_DIR } from "../config/constants"; export type FrontMatter = { slug: string; @@ -77,7 +78,7 @@ Promise => { slug, // validate/normalize the date string provided from front matter date: new Date(frontmatter.date).toISOString(), - permalink: `${BASE_URL}/${POSTS_DIR}/${slug}`, + permalink: `${env.NEXT_PUBLIC_BASE_URL}/${POSTS_DIR}/${slug}`, } as FrontMatter; } catch (error) { console.error(`Failed to load front matter for post with slug "${slug}":`, error); diff --git a/next.config.ts b/next.config.ts index 073ffa47..35930665 100644 --- a/next.config.ts +++ b/next.config.ts @@ -12,21 +12,6 @@ import "./lib/env"; const nextConfig: NextConfig = { reactStrictMode: true, productionBrowserSourceMaps: true, - env: { - // same logic as metadataBase: https://nextjs.org/docs/app/api-reference/functions/generate-metadata#default-value - NEXT_PUBLIC_BASE_URL: - process.env.VERCEL_ENV === "production" && process.env.VERCEL_PROJECT_PRODUCTION_URL - ? `https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}` - : process.env.VERCEL_ENV === "preview" && process.env.VERCEL_BRANCH_URL - ? `https://${process.env.VERCEL_BRANCH_URL}` - : process.env.VERCEL_URL - ? `https://${process.env.VERCEL_URL}` - : `http://localhost:${process.env.PORT || 3000}`, - - // freeze timestamp at build time for when server-side pages need a "last updated" date. calling Date.now() from - // pages using getServerSideProps will return the current(ish) time instead, which is usually not what we want. - NEXT_PUBLIC_RELEASE_TIMESTAMP: new Date().toISOString(), - }, pageExtensions: ["js", "jsx", "ts", "tsx", "md", "mdx"], outputFileTracingIncludes: { "/notes/[slug]/opengraph-image": [