mirror of
https://github.com/jakejarvis/jarv.is.git
synced 2026-06-05 19:35:27 -04:00
refactor: update font imports and variables
- Replaced GeistSans and GeistMono with Inter and JetBrainsMono in globals.css and layout.tsx. - Updated font variable names to reflect the new font choices in fonts.ts.
This commit is contained in:
+2
-2
@@ -6,9 +6,9 @@
|
||||
@custom-variant dark (&:where(.dark *));
|
||||
|
||||
@theme inline {
|
||||
--font-sans: var(--font-geist-sans);
|
||||
--font-sans: var(--font-inter);
|
||||
--font-sans--font-feature-settings: "rlig" 1, "calt" 0;
|
||||
--font-mono: var(--font-geist-mono);
|
||||
--font-mono: var(--font-jetbrains-mono);
|
||||
--font-mono--font-feature-settings: "liga" 0;
|
||||
--radius-sm: calc(var(--radius) - 4px);
|
||||
--radius-md: calc(var(--radius) - 2px);
|
||||
|
||||
+2
-2
@@ -7,7 +7,7 @@ import { Footer } from "@/components/layout/footer";
|
||||
import { Toaster } from "@/components/ui/sonner";
|
||||
import { Analytics } from "@/app/analytics";
|
||||
import { defaultMetadata } from "@/lib/metadata";
|
||||
import { GeistSans, GeistMono } from "@/lib/fonts";
|
||||
import { Inter, JetBrainsMono } from "@/lib/fonts";
|
||||
import siteConfig from "@/lib/config/site";
|
||||
import authorConfig from "@/lib/config/author";
|
||||
import type { Person, WebSite } from "schema-dts";
|
||||
@@ -20,7 +20,7 @@ const RootLayout = ({ children }: Readonly<{ children: React.ReactNode }>) => {
|
||||
return (
|
||||
<html
|
||||
lang={env.NEXT_PUBLIC_SITE_LOCALE}
|
||||
className={`${GeistSans.variable} ${GeistMono.variable}`}
|
||||
className={`${Inter.variable} ${JetBrainsMono.variable}`}
|
||||
suppressHydrationWarning
|
||||
>
|
||||
<head>
|
||||
|
||||
@@ -5,6 +5,7 @@ import { ImageResponse } from "next/og";
|
||||
import { notFound } from "next/navigation";
|
||||
import { getSlugs, getFrontMatter, POSTS_DIR } from "@/lib/posts";
|
||||
import siteConfig from "@/lib/config/site";
|
||||
import { loadGoogleFont } from "@/lib/og-utils";
|
||||
|
||||
export const contentType = "image/png";
|
||||
export const size = {
|
||||
@@ -53,16 +54,14 @@ const OpenGraphImage = async ({ params }: { params: Promise<{ slug: string }> })
|
||||
// get the post's title and image filename from its frontmatter
|
||||
const frontmatter = await getFrontMatter(slug);
|
||||
|
||||
const [postImg, avatarImg, fontRegular, fontSemiBold] = await Promise.all([
|
||||
frontmatter!.image ? getLocalImage(`${POSTS_DIR}/${slug}/${frontmatter!.image}`) : null,
|
||||
|
||||
// IMPORTANT: include these exact paths in next.config.ts under "outputFileTracingIncludes"
|
||||
const [postImg, avatarImg] = await Promise.all([
|
||||
frontmatter!.image ? getLocalImage(`${POSTS_DIR}/${slug}/${frontmatter!.image}`) : null,
|
||||
getLocalImage("app/avatar.jpg"),
|
||||
// load the Geist font directly from its npm package
|
||||
fs.promises.readFile(path.join(process.cwd(), "node_modules/geist/dist/fonts/geist-sans/Geist-Regular.ttf")),
|
||||
fs.promises.readFile(path.join(process.cwd(), "node_modules/geist/dist/fonts/geist-sans/Geist-SemiBold.ttf")),
|
||||
]);
|
||||
|
||||
const [fontRegular, fontSemibold] = await Promise.all([loadGoogleFont("Inter", 400), loadGoogleFont("Inter", 600)]);
|
||||
|
||||
// template is HEAVILY inspired by https://og-new.clerkstage.dev/
|
||||
return new ImageResponse(
|
||||
<div
|
||||
@@ -138,8 +137,7 @@ const OpenGraphImage = async ({ params }: { params: Promise<{ slug: string }> })
|
||||
<span
|
||||
style={{
|
||||
fontSize: "1.825rem",
|
||||
fontFamily: "Geist-SemiBold",
|
||||
fontWeight: 700,
|
||||
fontWeight: 600,
|
||||
lineHeight: "3rem",
|
||||
letterSpacing: "-0.015em",
|
||||
marginLeft: "0.75rem",
|
||||
@@ -153,8 +151,7 @@ const OpenGraphImage = async ({ params }: { params: Promise<{ slug: string }> })
|
||||
style={{
|
||||
display: "flex",
|
||||
flexGrow: 0,
|
||||
fontFamily: "Geist-SemiBold",
|
||||
fontWeight: 700,
|
||||
fontWeight: 600,
|
||||
fontSize: "48px",
|
||||
color: "#030712",
|
||||
letterSpacing: "-0.025em",
|
||||
@@ -172,7 +169,6 @@ const OpenGraphImage = async ({ params }: { params: Promise<{ slug: string }> })
|
||||
>
|
||||
<span
|
||||
style={{
|
||||
fontFamily: "Geist-Regular",
|
||||
fontWeight: 400,
|
||||
fontSize: "20px",
|
||||
color: "#030712",
|
||||
@@ -193,7 +189,6 @@ const OpenGraphImage = async ({ params }: { params: Promise<{ slug: string }> })
|
||||
style={{
|
||||
display: "flex",
|
||||
flexGrow: 0,
|
||||
fontFamily: "Geist-Regular",
|
||||
fontWeight: 400,
|
||||
fontSize: "24px",
|
||||
color: "#030712",
|
||||
@@ -235,16 +230,16 @@ const OpenGraphImage = async ({ params }: { params: Promise<{ slug: string }> })
|
||||
...size,
|
||||
fonts: [
|
||||
{
|
||||
name: "Geist-Regular",
|
||||
name: "Inter",
|
||||
data: fontRegular,
|
||||
style: "normal",
|
||||
weight: 400,
|
||||
},
|
||||
{
|
||||
name: "Geist-SemiBold",
|
||||
data: fontSemiBold,
|
||||
name: "Inter",
|
||||
data: fontSemibold,
|
||||
style: "normal",
|
||||
weight: 700,
|
||||
weight: 600,
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
@@ -9,15 +9,14 @@ const Footer = () => {
|
||||
<Link href="/license" className="underline underline-offset-4">
|
||||
{siteConfig.license}
|
||||
</Link>
|
||||
. Code is{" "}
|
||||
. View source on{" "}
|
||||
<a
|
||||
href={`https://github.com/${env.NEXT_PUBLIC_GITHUB_REPO}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
title="View Source on GitHub"
|
||||
className="underline underline-offset-4"
|
||||
>
|
||||
open source
|
||||
GitHub
|
||||
</a>
|
||||
.
|
||||
</footer>
|
||||
|
||||
+6
-6
@@ -2,22 +2,22 @@
|
||||
// https://nextjs.org/docs/pages/building-your-application/optimizing/fonts#reusing-fonts
|
||||
|
||||
import {
|
||||
Geist as GeistSansLoader,
|
||||
Geist_Mono as GeistMonoLoader,
|
||||
Inter as InterLoader,
|
||||
JetBrains_Mono as JetBrainsMonoLoader,
|
||||
Comic_Neue as ComicNeueLoader,
|
||||
} from "next/font/google";
|
||||
|
||||
export const GeistSans = GeistSansLoader({
|
||||
export const Inter = InterLoader({
|
||||
subsets: ["latin"],
|
||||
display: "swap",
|
||||
variable: "--font-geist-sans",
|
||||
variable: "--font-inter",
|
||||
preload: true,
|
||||
});
|
||||
|
||||
export const GeistMono = GeistMonoLoader({
|
||||
export const JetBrainsMono = JetBrainsMonoLoader({
|
||||
subsets: ["latin"],
|
||||
display: "swap",
|
||||
variable: "--font-geist-mono",
|
||||
variable: "--font-jetbrains-mono",
|
||||
preload: true,
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
import { cacheLife } from "next/cache";
|
||||
|
||||
// Load a Google Font from the Google Fonts API
|
||||
// Adapted from https://github.com/brianlovin/briOS/blob/f72dc33a11194de45c80337b22be4560da62ad7e/src/lib/og-utils.tsx#L32
|
||||
export async function loadGoogleFont(font: string, weight: number): Promise<ArrayBuffer> {
|
||||
"use cache";
|
||||
|
||||
const url = `https://fonts.googleapis.com/css2?family=${font}:wght@${weight}`;
|
||||
|
||||
const cssResponse = await fetch(url, {
|
||||
next: {
|
||||
revalidate: 31_536_000, // 1 year
|
||||
},
|
||||
});
|
||||
const css = await cssResponse.text();
|
||||
const resource = css.match(/src: url\((.+)\) format\('(opentype|truetype)'\)/);
|
||||
|
||||
if (resource) {
|
||||
const fontResponse = await fetch(resource[1], {
|
||||
next: {
|
||||
revalidate: 31_536_000, // 1 year
|
||||
},
|
||||
});
|
||||
if (fontResponse.status === 200) {
|
||||
cacheLife("max"); // cache indefinitely if successful
|
||||
return fontResponse.arrayBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error(`Failed to load font: ${font} ${weight}`);
|
||||
}
|
||||
+1
-6
@@ -22,12 +22,7 @@ const nextConfig = {
|
||||
],
|
||||
},
|
||||
outputFileTracingIncludes: {
|
||||
"/notes/[slug]/opengraph-image": [
|
||||
"./notes/**/*",
|
||||
"./app/opengraph-image.jpg",
|
||||
"./node_modules/geist/dist/fonts/geist-sans/Geist-Regular.ttf",
|
||||
"./node_modules/geist/dist/fonts/geist-sans/Geist-SemiBold.ttf",
|
||||
],
|
||||
"/notes/[slug]/opengraph-image": ["./notes/**/*", "./app/opengraph-image.jpg"],
|
||||
},
|
||||
productionBrowserSourceMaps: true,
|
||||
experimental: {
|
||||
|
||||
+16
-17
@@ -47,11 +47,11 @@
|
||||
"@radix-ui/react-toggle-group": "^1.1.11",
|
||||
"@radix-ui/react-tooltip": "^1.2.8",
|
||||
"@t3-oss/env-nextjs": "^0.13.10",
|
||||
"@tanstack/react-form": "^1.28.0",
|
||||
"@tanstack/react-form": "^1.28.3",
|
||||
"@vercel/analytics": "^1.6.1",
|
||||
"@vercel/functions": "^3.4.0",
|
||||
"@vercel/functions": "^3.4.2",
|
||||
"@vercel/speed-insights": "^1.3.1",
|
||||
"better-auth": "^1.4.17",
|
||||
"better-auth": "^1.4.18",
|
||||
"botid": "^1.5.10",
|
||||
"cheerio": "^1.2.0",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
@@ -60,18 +60,17 @@
|
||||
"drizzle-orm": "^0.45.1",
|
||||
"fast-glob": "^3.3.3",
|
||||
"feed": "^5.2.0",
|
||||
"geist": "^1.5.1",
|
||||
"html-entities": "^2.6.0",
|
||||
"lucide-react": "0.563.0",
|
||||
"lucide-react": "0.575.0",
|
||||
"next": "16.1.6",
|
||||
"next-themes": "^0.4.6",
|
||||
"pg": "^8.17.2",
|
||||
"pg": "^8.18.0",
|
||||
"react": "19.2.4",
|
||||
"react-activity-calendar": "^3.1.1",
|
||||
"react-compare-slider": "^3.1.0",
|
||||
"react-countup": "^6.5.3",
|
||||
"react-dom": "19.2.4",
|
||||
"react-lite-youtube-embed": "^3.3.3",
|
||||
"react-lite-youtube-embed": "~3.3.3",
|
||||
"react-markdown": "^10.1.0",
|
||||
"react-schemaorg": "^2.0.0",
|
||||
"react-timeago": "^8.3.0",
|
||||
@@ -92,12 +91,12 @@
|
||||
"remark-rehype": "^11.1.2",
|
||||
"remark-smartypants": "^3.0.2",
|
||||
"remark-strip-mdx-imports-exports": "^1.0.1",
|
||||
"resend": "^6.9.1",
|
||||
"resend": "^6.9.2",
|
||||
"server-only": "0.0.1",
|
||||
"shiki": "^3.21.0",
|
||||
"shiki": "^3.22.0",
|
||||
"sonner": "^2.0.7",
|
||||
"tailwind-merge": "^3.4.0",
|
||||
"tailwindcss": "^4.1.18",
|
||||
"tailwind-merge": "^3.5.0",
|
||||
"tailwindcss": "^4.2.0",
|
||||
"unified": "^11.0.5",
|
||||
"zod": "^4.3.6"
|
||||
},
|
||||
@@ -105,18 +104,18 @@
|
||||
"@eslint/eslintrc": "^3.3.3",
|
||||
"@eslint/js": "^9.39.2",
|
||||
"@jakejarvis/eslint-config": "^4.0.7",
|
||||
"@tailwindcss/postcss": "^4.1.18",
|
||||
"@tailwindcss/postcss": "^4.2.0",
|
||||
"@tailwindcss/typography": "^0.5.19",
|
||||
"@types/hast": "^3.0.4",
|
||||
"@types/mdx": "^2.0.13",
|
||||
"@types/node": "^25.1.0",
|
||||
"@types/node": "^25.3.0",
|
||||
"@types/pg": "^8.16.0",
|
||||
"@types/react": "19.2.10",
|
||||
"@types/react": "19.2.14",
|
||||
"@types/react-dom": "19.2.3",
|
||||
"babel-plugin-react-compiler": "19.1.0-rc.3",
|
||||
"cross-env": "^10.1.0",
|
||||
"dotenv": "^17.2.3",
|
||||
"drizzle-kit": "^0.31.8",
|
||||
"dotenv": "^17.3.1",
|
||||
"drizzle-kit": "^0.31.9",
|
||||
"eslint": "^9.39.2",
|
||||
"eslint-config-next": "16.1.6",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
@@ -141,7 +140,7 @@
|
||||
"engines": {
|
||||
"node": ">=24.x"
|
||||
},
|
||||
"packageManager": "pnpm@10.28.2+sha512.41872f037ad22f7348e3b1debbaf7e867cfd448f2726d9cf74c08f19507c31d2c8e7a11525b983febc2df640b5438dee6023ebb1f84ed43cc2d654d2bc326264",
|
||||
"packageManager": "pnpm@10.30.0+sha512.2b5753de015d480eeb88f5b5b61e0051f05b4301808a82ec8b840c9d2adf7748eb352c83f5c1593ca703ff1017295bc3fdd3119abb9686efc96b9fcb18200937",
|
||||
"cacheDirectories": [
|
||||
"node_modules",
|
||||
".next/cache"
|
||||
|
||||
Generated
+657
-825
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user