Skip to content

Commit 09a8692

Browse files
authored
Merge pull request #3 from pheralb/next
Docs, Fonts, Og Image & Metatags 🚀
2 parents 6dadbbd + 94fad26 commit 09a8692

32 files changed

Lines changed: 1654 additions & 1226 deletions

apps/website/eslint.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { defineConfig } from "eslint/config";
22

33
// Plugins:
4-
import { nextConfig } from "@pheralb/cb-eslint/nextjs";
4+
import { nextConfig } from "@code-blocks/eslint/nextjs";
55

66
const eslintConfig = defineConfig(nextConfig);
77

apps/website/package.json

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
2-
"name": "@pheralb/cb-website",
3-
"version": "1.0.0",
2+
"name": "@code-blocks/website",
3+
"version": "1.0.1",
44
"private": true,
55
"scripts": {
66
"dev": "next dev",
@@ -18,33 +18,33 @@
1818
"class-variance-authority": "0.7.1",
1919
"clsx": "2.1.1",
2020
"cmdk": "1.1.1",
21-
"lucide-react": "0.562.0",
22-
"motion": "12.23.26",
23-
"next": "16.1.1",
21+
"lucide-react": "0.563.0",
22+
"motion": "12.29.2",
23+
"next": "16.1.6",
2424
"next-themes": "0.4.6",
2525
"radix-ui": "1.4.3",
26-
"react": "19.2.3",
27-
"react-dom": "19.2.3",
28-
"shadcn": "3.6.2",
26+
"react": "19.2.4",
27+
"react-dom": "19.2.4",
28+
"shadcn": "3.8.1",
2929
"tailwind-merge": "3.4.0",
30-
"zod": "4.2.1",
31-
"zustand": "5.0.9"
30+
"zod": "4.3.6",
31+
"zustand": "5.0.11"
3232
},
3333
"devDependencies": {
34+
"@code-blocks/eslint": "workspace:*",
3435
"@content-collections/cli": "0.1.8",
35-
"@content-collections/core": "0.13.0",
36+
"@content-collections/core": "0.13.1",
3637
"@content-collections/mdx": "0.2.2",
3738
"@content-collections/next": "0.2.10",
38-
"@pheralb/cb-eslint": "workspace:*",
39-
"@shikijs/langs": "3.20.0",
40-
"@shikijs/rehype": "3.20.0",
41-
"@shikijs/themes": "3.20.0",
42-
"@shikijs/transformers": "3.20.0",
39+
"@shikijs/langs": "3.22.0",
40+
"@shikijs/rehype": "3.22.0",
41+
"@shikijs/themes": "3.22.0",
42+
"@shikijs/transformers": "3.22.0",
4343
"@tailwindcss/postcss": "4.1.18",
4444
"@tailwindcss/typography": "0.5.19",
4545
"@types/mdx": "2.0.13",
46-
"@types/node": "20.19.27",
47-
"@types/react": "19.2.7",
46+
"@types/node": "22.19.7",
47+
"@types/react": "19.2.10",
4848
"@types/react-dom": "19.2.3",
4949
"chalk": "5.6.2",
5050
"eslint": "9.39.2",
@@ -53,13 +53,13 @@
5353
"rehype-autolink-headings": "7.1.0",
5454
"rehype-slug": "6.0.0",
5555
"remark-gfm": "4.0.1",
56-
"shiki": "3.20.0",
56+
"shiki": "3.22.0",
5757
"sugar-high": "0.9.5",
5858
"tailwindcss": "4.1.18",
5959
"tsx": "4.21.0",
6060
"tw-animate-css": "1.4.0",
6161
"typescript": "5.9.3",
6262
"unist-builder": "4.0.0",
63-
"unist-util-visit": "5.0.0"
63+
"unist-util-visit": "5.1.0"
6464
}
6565
}
10.2 KB
Binary file not shown.
90.1 KB
Loading
Lines changed: 1 addition & 0 deletions
Loading
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import path from "path";
2+
import fs from "fs/promises";
3+
4+
import { ImageResponse } from "next/og";
5+
import { getDocument } from "@/utils/docs";
6+
7+
// Template
8+
import DocumentOgImage from "@/components/docs/doc-og-image";
9+
10+
// Settings
11+
const cacheTime = 60 * 60 * 24;
12+
const isDevMode = process.env.NODE_ENV === "development";
13+
const cacheControl = `public, no-transform, max-age=${cacheTime}, immutable`;
14+
15+
export async function GET(request: Request) {
16+
const { searchParams } = new URL(request.url);
17+
const folder = searchParams.get("folder");
18+
const document = searchParams.get("document");
19+
20+
if (!document || !folder) {
21+
return new Response(
22+
`|- api/og - Missing folder or document parameter. Folder: ${folder}, Document: ${document}.`,
23+
{ status: 400 },
24+
);
25+
}
26+
27+
const docData = getDocument({
28+
folder: folder,
29+
document: document,
30+
});
31+
32+
if (!docData) {
33+
return new Response(`|- api/og - ${document} document not found.`, {
34+
status: 404,
35+
});
36+
}
37+
38+
return new ImageResponse(
39+
<DocumentOgImage title={docData.title} description={docData.description} />,
40+
{
41+
width: 1200,
42+
height: 630,
43+
fonts: [
44+
{
45+
name: "Geist",
46+
style: "normal",
47+
data: await fs.readFile(
48+
path.join(process.cwd(), "src/styles/fonts/Geist-Regular.ttf"),
49+
),
50+
},
51+
{
52+
name: "Onest",
53+
style: "normal",
54+
data: await fs.readFile(
55+
path.join(process.cwd(), "src/styles/fonts/Onest-SemiBold.ttf"),
56+
),
57+
},
58+
],
59+
headers: {
60+
"Cache-Control": isDevMode ? "no-cache" : cacheControl,
61+
},
62+
},
63+
);
64+
}

apps/website/src/app/docs/[folder]/[...slug]/page.tsx

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,16 @@ import type { Metadata } from "next";
33
import { globals } from "@/globals";
44
import { notFound } from "next/navigation";
55

6-
import MDX from "@/components/mdx";
76
import { cn } from "@/utils/cn";
87
import { getDocument } from "@/utils/docs";
98

10-
import Article from "@/components/docs/doc-article";
9+
import MDX from "@/components/mdx";
1110
import Container from "@/components/container";
11+
import Article from "@/components/docs/doc-article";
12+
13+
import DocOptions from "@/components/docs/doc-options";
1214
import TableOfContents from "@/components/docs/toc-menu";
1315
import ShowCategories from "@/components/docs/show-categories";
14-
import DocOptions from "@/components/docs/doc-options";
1516

1617
interface DocsPageProps {
1718
params: Promise<{ folder: string; slug: string[] }>;
@@ -22,13 +23,29 @@ export async function generateMetadata({
2223
}: DocsPageProps): Promise<Metadata> {
2324
const { folder, slug } = await params;
2425
const document = slug.join("/");
26+
const websiteUrl = "https://code-blocks.pheralb.dev";
2527
const data = getDocument({
2628
folder,
2729
document,
2830
});
2931
return {
3032
title: `${data?.title} - ${globals.title}`,
3133
description: data?.description,
34+
openGraph: {
35+
type: "website",
36+
url: new URL(`/${slug}`, websiteUrl),
37+
title: `${data?.title} - ${globals.title}`,
38+
description: data?.description,
39+
siteName: websiteUrl,
40+
images: [
41+
{
42+
url: new URL(
43+
`/api/docs/og?document=${document}&folder=${folder}`,
44+
websiteUrl,
45+
),
46+
},
47+
],
48+
},
3249
};
3350
}
3451

@@ -51,7 +68,7 @@ const DocsPage = async ({ params }: DocsPageProps) => {
5168
<DocOptions
5269
content={data.content}
5370
folder={data.folder}
54-
file={data._meta.fileName}
71+
file={`${document}.mdx`}
5572
/>
5673
</div>
5774
<p className="text-lg text-neutral-600 dark:text-neutral-400">

apps/website/src/app/layout.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,18 @@ import { globals } from "@/globals";
1515

1616
// Metadata:
1717
export const metadata: Metadata = {
18+
metadataBase: new URL(globals.websiteUrl),
1819
title: `${globals.subTitle} - ${globals.title}`,
1920
description: "A code-block UI component. Copy-Paste. Customizable.",
2021
authors: [{ name: "pheralb", url: "https://pheralb.dev" }],
22+
robots: "follow, index",
23+
alternates: {
24+
canonical: "/",
25+
},
26+
icons: [
27+
{ rel: "icon", type: "ico", url: "/images/code-blocks-ico.ico" },
28+
{ rel: "icon", type: "image/svg+xml", url: "/images/code-blocks-svg.svg" },
29+
],
2130
};
2231

2332
export default function RootLayout({

apps/website/src/app/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ const Home = () => {
1818
<>
1919
<Container>
2020
<Header layout="app" />
21-
<Article className="pb-12">
21+
<Article className="pb-14">
2222
<MDX code={document.mdx} />
2323
</Article>
2424
</Container>
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import { LogoWithBg } from "@/components/logo";
2+
3+
interface DocOgImageProps {
4+
title: string;
5+
description?: string;
6+
}
7+
8+
const DocOgImage = ({ title, description }: DocOgImageProps) => {
9+
return (
10+
<div
11+
style={{
12+
height: "100%",
13+
width: "100%",
14+
display: "flex",
15+
flexDirection: "column",
16+
justifyContent: "space-between",
17+
backgroundColor: "#171717",
18+
border: "1px dashed #262626",
19+
color: "#fafafa",
20+
paddingTop: "40px",
21+
paddingBottom: "76px",
22+
paddingLeft: "60px",
23+
paddingRight: "60px",
24+
}}
25+
>
26+
<div
27+
style={{
28+
display: "flex",
29+
justifyContent: "space-between",
30+
alignItems: "center",
31+
}}
32+
>
33+
<h2
34+
style={{
35+
flexDirection: "column",
36+
fontSize: "30px",
37+
fontWeight: "bold",
38+
fontFamily: "Geist",
39+
}}
40+
>
41+
<span
42+
style={{
43+
fontSize: "20px",
44+
color: "#a1a1a1",
45+
}}
46+
>
47+
pheralb
48+
</span>
49+
<span>Code Blocks</span>
50+
</h2>
51+
<LogoWithBg width="52px" height="52px" />
52+
</div>
53+
<div
54+
style={{
55+
display: "flex",
56+
flexDirection: "column",
57+
}}
58+
>
59+
{/* Document Title */}
60+
<h1
61+
style={{
62+
fontFamily: "Onest",
63+
fontSize: "80px",
64+
fontWeight: "bolder",
65+
marginTop: "44px",
66+
marginBottom: "10px",
67+
lineHeight: "1.1",
68+
}}
69+
>
70+
{title}
71+
</h1>
72+
{/* Document Description */}
73+
<p
74+
style={{
75+
fontSize: "32px",
76+
color: "#a1a1a1",
77+
margin: "0px",
78+
fontWeight: "normal",
79+
fontFamily: "Geist",
80+
}}
81+
>
82+
{description}
83+
</p>
84+
</div>
85+
</div>
86+
);
87+
};
88+
89+
export default DocOgImage;

0 commit comments

Comments
 (0)