mirror of
https://github.com/supabase/supabase.git
synced 2026-10-06 01:45:10 +03:00
feat: add new 'articles' section to KB
This commit is contained in:
1 parent
13de8189c9
commit
897dd41925
6 files changed
+307
-1
No files matched your search
@@ -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 }
|
||||
@@ -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:
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
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.
|
||||
@@ -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:
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
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.
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
import Layout from './Layout.astro'
|
||||
|
||||
interface Props {
|
||||
title: string
|
||||
description?: string
|
||||
formattedDate: string
|
||||
}
|
||||
|
||||
const { title, description, formattedDate } = Astro.props
|
||||
---
|
||||
|
||||
<Layout title={title} description={description}>
|
||||
<article class="prose max-w-3xl mx-auto px-6 py-16">
|
||||
<h1>{title}</h1>
|
||||
<p>{formattedDate}</p>
|
||||
{description && <p class="lead">{description}</p>}
|
||||
<slot />
|
||||
</article>
|
||||
</Layout>
|
||||
@@ -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)
|
||||
---
|
||||
|
||||
<ArticleLayout title={title} description={description} formattedDate={formattedDate}>
|
||||
<Content components={{ Admonition }} />
|
||||
</ArticleLayout>
|
||||
@@ -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()
|
||||
)
|
||||
---
|
||||
|
||||
<Layout title="Articles" description="Long-form articles on Supabase and the broader database ecosystem">
|
||||
<div class="mx-auto flex max-w-7xl flex-col gap-12 px-6 py-16">
|
||||
<section id="articles" class="flex flex-col gap-1">
|
||||
<div class="mb-8 flex items-center justify-between border-b border-border pb-4">
|
||||
<h1 class="text-l font-semibold uppercase tracking-widest text-muted-foreground">Articles</h1>
|
||||
</div>
|
||||
|
||||
<ul class="flex flex-col gap-0">
|
||||
{sortedArticles.map((article, idx) => (
|
||||
<li class={`border-b border-border py-8 ${idx === sortedArticles.length - 1 ? 'border-b-0' : ''}`}>
|
||||
<a
|
||||
href={`${import.meta.env.BASE_URL}/articles/${article.id}`}
|
||||
class="group flex flex-col gap-2 hover:opacity-70 transition-opacity"
|
||||
>
|
||||
<div class="flex items-start justify-between gap-4">
|
||||
<h3 class="flex-1 text-xl font-semibold leading-tight text-foreground group-hover:underline">
|
||||
{article.data.title}
|
||||
</h3>
|
||||
<div class="flex-shrink-0 whitespace-nowrap text-right text-xs text-muted-foreground">
|
||||
{article.data.formattedDate}
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-sm text-muted-foreground">{article.data.description}</p>
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
</Layout>
|
||||
Reference in new issue
Block a user