)}
diff --git a/components/Time/Time.tsx b/components/Time/Time.tsx
index 7323acdf..70b33281 100644
--- a/components/Time/Time.tsx
+++ b/components/Time/Time.tsx
@@ -2,7 +2,7 @@ import { format, formatISO } from "date-fns";
import { enUS } from "date-fns/locale";
import { tz } from "@date-fns/tz";
import { utc } from "@date-fns/utc";
-import * as config from "../../lib/config";
+import { SITE_TZ } from "../../lib/config/constants";
import type { ComponentPropsWithoutRef } from "react";
export type TimeProps = ComponentPropsWithoutRef<"time"> & {
@@ -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 65793fb1..cb02c029 100644
--- a/lib/config/constants.ts
+++ b/lib/config/constants.ts
@@ -1,13 +1,30 @@
-// path to directory with .mdx files, relative to project root
+/**
+ * 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";
-// path to an image used in various places to represent the site, relative to project root
-// IMPORTANT: must be included in next.config.ts under "outputFileTracingIncludes"
+/**
+ * Path to an image used in various places to represent the site, relative to project root. This path must be included
+ * in [next.config.ts](../../next.config.ts) under `outputFileTracingIncludes`.
+ */
export const AVATAR_PATH = "app/avatar.jpg";
-// maximum width of content wrapper (e.g. for images) in pixels
+/** Maximum width of content wrapper (e.g. for images) in pixels. */
export const MAX_WIDTH = 865;
-// defined in next.config.ts
+/** 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 eb4b659b..e48bf4ea 100644
--- a/lib/config/index.ts
+++ b/lib/config/index.ts
@@ -1,9 +1,7 @@
// Site info
export const siteName = "Jake Jarvis";
-export const siteLocale = "en-US";
-export const timeZone = "America/New_York"; // https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List
-export const shortDescription = "Frontend Web Developer in Boston, MA";
-export const longDescription =
+export const tagline = "Frontend Web Developer in Boston, MA";
+export const description =
"Hi there! I'm a frontend web developer based in Boston, Massachusetts specializing in TypeScript, React, Next.js, and other JavaScript frameworks.";
export const license = "Creative Commons Attribution 4.0 International";
export const licenseAbbr = "CC-BY-4.0";
diff --git a/lib/env.ts b/lib/env.ts
index 38accf77..af205b68 100644
--- a/lib/env.ts
+++ b/lib/env.ts
@@ -11,15 +11,15 @@ export const env = createEnv({
],
server: {
/**
- * Required. GitHub API token used for /projects grid. Only needs the `public_repo` scope since we don't need/want
- * to change anything, obviously.
+ * Required. GitHub API token used for [/projects](../app/projects/page.tsx) grid. Only needs the `public_repo`
+ * scope since we don't need/want to change anything, obviously.
*
* @see https://github.com/settings/tokens/new?scopes=public_repo
*/
GITHUB_TOKEN: v.optional(v.pipe(v.string(), v.startsWith("ghp_"))),
/**
- * Required. Redis storage credentials for hit counter's server component (app/notes/[slug]/counter.tsx) and API
+ * Required. Redis storage credentials for hit counter's [server component](../app/notes/[slug]/counter.tsx) and API
* endpoint. Currently set automatically by Vercel's Upstash integration.
*
* @see https://upstash.com/docs/redis/sdks/ts/getstarted
@@ -27,7 +27,7 @@ export const env = createEnv({
*/
KV_REST_API_TOKEN: v.string(),
/**
- * Required. Redis storage credentials for hit counter's server component (app/notes/[slug]/counter.tsx) and API
+ * Required. Redis storage credentials for hit counter's [server component](../app/notes/[slug]/counter.tsx) and API
* endpoint. Currently set automatically by Vercel's Upstash integration.
*
* @see https://upstash.com/docs/redis/sdks/ts/getstarted
@@ -36,7 +36,7 @@ export const env = createEnv({
KV_REST_API_URL: v.pipe(v.string(), v.url(), v.startsWith("https://"), v.endsWith(".upstash.io")),
/**
- * Required. Uses Resend API to send contact form submissions via a server action (see app/contact/actions.ts). May
+ * Required. Uses Resend API to send contact form submissions via a [server action](../app/contact/action.ts). May
* be set automatically by Vercel's Resend integration.
*
* @see https://resend.com/api-keys
diff --git a/lib/helpers/build-feed.ts b/lib/helpers/build-feed.ts
index 94718402..033273a7 100644
--- a/lib/helpers/build-feed.ts
+++ b/lib/helpers/build-feed.ts
@@ -15,7 +15,7 @@ export const buildFeed = async (): Promise => {
id: `${BASE_URL}`,
link: `${BASE_URL}`,
title: config.siteName,
- description: config.longDescription,
+ description: config.description,
copyright: config.licenseUrl,
updated: new Date(RELEASE_TIMESTAMP),
image: `${BASE_URL}${ogImage.src}`,
diff --git a/lib/helpers/metadata.ts b/lib/helpers/metadata.ts
index f818c15c..43033d2d 100644
--- a/lib/helpers/metadata.ts
+++ b/lib/helpers/metadata.ts
@@ -1,22 +1,22 @@
import * as config from "../config";
-import { BASE_URL } from "../config/constants";
+import { BASE_URL, SITE_LOCALE } from "../config/constants";
import type { Metadata } from "next";
export const defaultMetadata: Metadata = {
metadataBase: new URL(BASE_URL),
title: {
template: `%s – ${config.siteName}`,
- default: `${config.siteName} – ${config.shortDescription}`,
+ default: `${config.siteName} – ${config.tagline}`,
},
- description: config.longDescription,
+ description: config.description,
openGraph: {
siteName: config.siteName,
title: {
template: "%s",
- default: `${config.siteName} – ${config.shortDescription}`,
+ default: `${config.siteName} – ${config.tagline}`,
},
url: "/",
- locale: config.siteLocale?.replace("-", "_"),
+ locale: SITE_LOCALE?.replace("-", "_"),
type: "website",
},
twitter: {