Skip to content

Content & blog

varsha uses Astro’s content collections to manage Markdown and MDX content for the blog and documentation. This guide covers how to write, organize, and publish content.

Content collections are defined in src/content.config.ts. varsha configures two collections out of the box:

CollectionDirectoryPurposeFormat
blogsrc/content/blog/Blog postsMarkdown (.md)
docssrc/content/docs/DocumentationMDX (.mdx)

Each collection has a schema that validates frontmatter fields and provides TypeScript type safety.

Create a new .md file in src/content/blog/ to publish a blog post:

src/content/blog/launching-varsha.md
---
title: "Launching varsha: A premium website starter"
description: "Why we built varsha and how it helps founders ship faster."
date: "2025-01-20"
author: "Your Name"
tags: ["starter", "astro"]
---
This is the body of your blog post. It supports full Markdown syntax.
## Features
- Bullet lists work
- **Bold** and *italic* text
- [Links](https://myndlabs.tech)
- `inline code`
### Code blocks
```js
console.log("Hello from varsha!");

Blockquotes are also styled.

### Blog post frontmatter
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `title` | `string` | Yes | Post title (also used for SEO) |
| `description` | `string` | Yes | Short summary for meta tags and listing pages |
| `date` | `string` (ISO date) | Yes | Publication date (e.g., `"2025-01-20"`) |
| `author` | `string` | No | Author name displayed on the post |
| `ogImage` | `string` | No | Path to an Open Graph/social share image for the post |
| `tags` | `string[]` | No | Array of tags for categorization |
| `draft` | `boolean` | No | If `true`, the post is not published in production |
### Draft posts
Set `draft: true` in frontmatter to exclude a post from production builds:
```md
---
title: "Work in progress"
description: "This post is not ready yet."
date: "2025-02-01"
draft: true
---

Drafts are visible during development (npm run dev) but excluded from npm run build.

Place blog post images in public/assets/blog/ or in src/assets/ for Astro-optimized images. Reference them in Markdown:

![Alt text for the image](/assets/blog/my-image.png)

Documentation pages use MDX, which allows you to embed React/Astro components and use richer formatting than plain Markdown.

Create an .mdx file in src/content/docs/ (or a locale subdirectory):

src/content/docs/new-page.mdx
---
title: "My New Doc Page"
description: "A brief description of this page."
---
import { Card, CardGrid } from '@astrojs/starlight/components';
Content goes here. You can use **Markdown** syntax and import components.
<CardGrid>
<Card title="Related">
Link to related pages.
</Card>
</CardGrid>

Starlight supports a rich set of frontmatter fields for docs:

FieldTypeDescription
titlestringPage title (required)
descriptionstringMeta description (required)
slugstringOverride the auto-generated URL slug
template'doc' | 'splash'Page template (splash for wide hero landing pages)
heroobjectHero configuration for splash pages
sidebarobjectSidebar configuration (label, order, group)
headarrayAdditional tags to inject into <head>
lastUpdatedbooleanShow last updated date
prevboolean | { label, link }Previous page navigation override
nextboolean | { label, link }Next page navigation override
pagefindbooleanWhether to include in search (default: true)

Every doc page can use Starlight’s built-in components. Import them at the top of your MDX file:

import { Card, CardGrid, Tabs, TabItem, Steps, Aside } from '@astrojs/starlight/components';

Card and CardGrid:

<CardGrid>
<Card title="Feature one" icon="rocket">
Description of feature one.
</Card>
<Card title="Feature two" icon="puzzle">
Description of feature two.
</Card>
</CardGrid>

Tabs:

<Tabs>
<TabItem label="npm">
npm install
</TabItem>
<TabItem label="pnpm">
pnpm install
</TabItem>
</Tabs>

Aside callouts:

:::tip[Pro tip]
This is a helpful tip.
:::
:::caution
This action cannot be undone.
:::
:::danger[Critical]
Read this before proceeding.
:::

Steps:

<Steps>
1. First, do this.
2. Then, do that.
3. Finally, verify.
</Steps>

Use relative paths or root-relative paths for internal links:

[Getting started](/docs/install/)
[Project structure](/docs/concepts/)

Starlight automatically resolves locale-specific links. In Japanese or Chinese docs, links like /docs/install/ will automatically resolve to /ja/docs/install/ or /zh-cn/docs/install/.

The src/content/docs/ directory follows Starlight’s locale structure:

src/content/docs/
├── index.mdx # English (root locale)
├── install.mdx
├── ja/
│ ├── index.mdx # Japanese
│ └── install.mdx
└── zh-cn/
├── index.mdx # Simplified Chinese
└── install.mdx

When adding a new English doc page, create corresponding translated files in ja/ and zh-cn/ to keep the documentation complete across locales.

The blog listing page at src/pages/blog/index.astro automatically displays all published (non-draft) blog posts sorted by date. You do not need to manually update it when adding new posts.

If you want to add an RSS feed for the blog, install the Astro RSS package:

Terminal window
npm install @astrojs/rss

Then create src/pages/rss.xml.js:

src/pages/rss.xml.js
import rss from '@astrojs/rss';
import { getCollection } from 'astro:content';
import { site } from '../../consts';
export async function GET(context) {
const posts = await getCollection('blog');
return rss({
title: 'varsha Blog',
description: 'News and updates from varsha.',
site: context.site,
items: posts.map((post) => ({
...post.data,
link: `/blog/${post.slug}/`,
})),
});
}

Components reference

Use Starlight and custom components in your MDX content.

Components →

SEO & metadata

Optimize your content for search engines and social sharing.

SEO & metadata →