diff --git a/apps/kb/src/content.config.ts b/apps/kb/src/content.config.ts index d67a7e17b1f..3028bce7355 100644 --- a/apps/kb/src/content.config.ts +++ b/apps/kb/src/content.config.ts @@ -4,6 +4,19 @@ import { z } from 'astro/zod' import { TOPIC_NAMES } from './lib/topics' +// Format date as "26 SEPTEMBER 2026" +const formatDate = (date: Date): string => { + // Adjust for timezone offset to preserve the intended date + const adjusted = new Date(date.getTime() + date.getTimezoneOffset() * 60000) + return new Intl.DateTimeFormat('en-US', { + year: 'numeric', + month: 'long', + day: 'numeric', + }) + .format(adjusted) + .toUpperCase() +} + // Every entry here is rendered through GuideLayout by // src/pages/guides/[...slug].astro — dropping a new file in // src/content/guides doesn't need any per-file layout wiring. @@ -21,4 +34,18 @@ const guides = defineCollection({ }), }) -export const collections = { guides } +const articles = defineCollection({ + loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/articles' }), + schema: z + .object({ + title: z.string(), + description: z.string(), + date: z.date(), + }) + .transform((data) => ({ + ...data, + formattedDate: formatDate(data.date), + })), +}) + +export const collections = { guides, articles } diff --git a/apps/kb/src/content/articles/sample-article-2.mdx b/apps/kb/src/content/articles/sample-article-2.mdx new file mode 100644 index 00000000000..d89f68552eb --- /dev/null +++ b/apps/kb/src/content/articles/sample-article-2.mdx @@ -0,0 +1,97 @@ +--- +title: 'Sample article 2' +description: 'A lorem ipsum sample guide exercising every base Markdown element supported by the guide layout.' +date: 2026-09-29 +--- + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor +incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis +nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. + +## Heading level 2 + +Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore +eu fugiat nulla pariatur. This paragraph mixes **bold text**, _italic text_, +**_bold italic text_**, ~~strikethrough text~~, and `inline code`. + +### Heading level 3 + +Here's a [link to the Astro docs](https://docs.astro.build/en/basics/layouts/), +followed by an unordered list with a nested list: + +- Excepteur sint occaecat cupidatat non proident +- Sunt in culpa qui officia deserunt mollit anim id est laborum + - Nested item one + - Nested item two +- Curabitur blandit tempus porttitor + +#### Heading level 4 + +And an ordered list with a nested list: + +1. Lorem ipsum dolor sit amet +2. Consectetur adipiscing elit + 1. Nested step one + 2. Nested step two +3. Sed do eiusmod tempor incididunt + +##### Heading level 5 + +> Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, +> consectetur, adipisci velit. +> +> > Nested blockquote: at vero eos et accusamus et iusto odio dignissimos. + +GitHub-style alert blockquotes, rendered through the `Admonition` component: + +> [!NOTE] +> Useful information that users should know, even when skimming content. + +> [!TIP] +> Helpful advice for doing things better or more easily. + +> [!IMPORTANT] +> Key information users need to know to achieve their goal. + +> [!WARNING] +> Urgent info that needs immediate attention to avoid problems. + +> [!CAUTION] +> Advises about risks or negative outcomes of certain actions. + +###### Heading level 6 + +A fenced code block with a language tag: + +```js +function add(a, b) { + return a + b +} + +console.log(add(2, 3)) +``` + +And another in a different language: + +```bash +npm install +npm run dev +``` + +A table: + +| Element | Supported | Notes | +| -------- | --------- | ---------------------------- | +| Headings | Yes | h2 through h6 | +| Tables | Yes | via GitHub-flavored Markdown | +| Images | Yes | see below | + +An image: + +![Placeholder image](https://placehold.co/800x400?text=Placeholder+Image) + +--- + +Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium +doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore +veritatis et quasi architecto beatae vitae dicta sunt explicabo. diff --git a/apps/kb/src/content/articles/sample-article.mdx b/apps/kb/src/content/articles/sample-article.mdx new file mode 100644 index 00000000000..d103b8efcd0 --- /dev/null +++ b/apps/kb/src/content/articles/sample-article.mdx @@ -0,0 +1,97 @@ +--- +title: 'Sample article' +description: 'A lorem ipsum sample guide exercising every base Markdown element supported by the guide layout.' +date: 2026-09-30 +--- + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor +incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis +nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. + +## Heading level 2 + +Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore +eu fugiat nulla pariatur. This paragraph mixes **bold text**, _italic text_, +**_bold italic text_**, ~~strikethrough text~~, and `inline code`. + +### Heading level 3 + +Here's a [link to the Astro docs](https://docs.astro.build/en/basics/layouts/), +followed by an unordered list with a nested list: + +- Excepteur sint occaecat cupidatat non proident +- Sunt in culpa qui officia deserunt mollit anim id est laborum + - Nested item one + - Nested item two +- Curabitur blandit tempus porttitor + +#### Heading level 4 + +And an ordered list with a nested list: + +1. Lorem ipsum dolor sit amet +2. Consectetur adipiscing elit + 1. Nested step one + 2. Nested step two +3. Sed do eiusmod tempor incididunt + +##### Heading level 5 + +> Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, +> consectetur, adipisci velit. +> +> > Nested blockquote: at vero eos et accusamus et iusto odio dignissimos. + +GitHub-style alert blockquotes, rendered through the `Admonition` component: + +> [!NOTE] +> Useful information that users should know, even when skimming content. + +> [!TIP] +> Helpful advice for doing things better or more easily. + +> [!IMPORTANT] +> Key information users need to know to achieve their goal. + +> [!WARNING] +> Urgent info that needs immediate attention to avoid problems. + +> [!CAUTION] +> Advises about risks or negative outcomes of certain actions. + +###### Heading level 6 + +A fenced code block with a language tag: + +```js +function add(a, b) { + return a + b +} + +console.log(add(2, 3)) +``` + +And another in a different language: + +```bash +npm install +npm run dev +``` + +A table: + +| Element | Supported | Notes | +| -------- | --------- | ---------------------------- | +| Headings | Yes | h2 through h6 | +| Tables | Yes | via GitHub-flavored Markdown | +| Images | Yes | see below | + +An image: + +![Placeholder image](https://placehold.co/800x400?text=Placeholder+Image) + +--- + +Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium +doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore +veritatis et quasi architecto beatae vitae dicta sunt explicabo. diff --git a/apps/kb/src/layouts/ArticleLayout.astro b/apps/kb/src/layouts/ArticleLayout.astro new file mode 100644 index 00000000000..d2678bb76e4 --- /dev/null +++ b/apps/kb/src/layouts/ArticleLayout.astro @@ -0,0 +1,20 @@ +--- +import Layout from './Layout.astro' + +interface Props { + title: string + description?: string + formattedDate: string +} + +const { title, description, formattedDate } = Astro.props +--- + + +
+

{title}

+

{formattedDate}

+ {description &&

{description}

} + +
+
diff --git a/apps/kb/src/pages/articles/[...slug].astro b/apps/kb/src/pages/articles/[...slug].astro new file mode 100644 index 00000000000..82cc1261798 --- /dev/null +++ b/apps/kb/src/pages/articles/[...slug].astro @@ -0,0 +1,22 @@ +--- +import { getCollection, render } from 'astro:content' +import { Admonition } from 'ui-patterns/Admonition' + +import ArticleLayout from '../../layouts/ArticleLayout.astro' + +export async function getStaticPaths() { + const articles = await getCollection('articles') + return articles.map((article) => ({ + params: { slug: article.id }, + props: { article }, + })) +} + +const { article } = Astro.props +const { title, description, formattedDate } = article.data +const { Content } = await render(article) +--- + + + + diff --git a/apps/kb/src/pages/articles/index.astro b/apps/kb/src/pages/articles/index.astro new file mode 100644 index 00000000000..3c5da907bf7 --- /dev/null +++ b/apps/kb/src/pages/articles/index.astro @@ -0,0 +1,43 @@ +--- +import { getCollection } from 'astro:content' + +import Layout from '../../layouts/Layout.astro' + +const articles = await getCollection('articles') + +// Sort articles by date, newest first +const sortedArticles = articles.sort( + (a, b) => new Date(b.data.date).getTime() - new Date(a.data.date).getTime() +) +--- + + +
+
+
+

Articles

+
+ + +
+
+