Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
(code); dark theme is now the default with a persisted light/dark toggle.
- Homepage hero image swapped from a remote Midjourney-hosted asset to the
self-hosted `public/demo/oss_landingpage.webp`.
- README rewritten with a hero value proposition, "Why ossium?" comparison,
grouped features, screenshots, corrected tech stack (Next.js 16, unified
remark/rehype pipeline), and a scannable quickstart; covered by a
`lib/readme.test.ts` regression suite.

## [0.1.0]- 2026-07-11

Expand Down
229 changes: 145 additions & 84 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,124 +1,150 @@
# Ossium Blog
# ossium Blog

The official blog of [Ossium](https://ossium.in) - practical guides, how-tos, and Q&A on open source contribution, GSoC, good first issues, GitHub workflows, and tools for contributors.
> From first issue to first merge — practical guides, how-tos, and Q&A that help
> developers land their first open-source contribution, crack GSoC, and ship with
> confidence.

[![CI](https://img.shields.io/github/actions/workflow/status/MxCorpIn/blogs/ci.yml?branch=main&label=CI)](https://github.com/MxCorpIn/blogs/actions/workflows/ci.yml)
[![Stars](https://img.shields.io/github/stars/MxCorpIn/blogs)](https://github.com/MxCorpIn/blogs)
[![Last commit](https://img.shields.io/github/last-commit/MxCorpIn/blogs)](https://github.com/MxCorpIn/blogs/commits/main)
[![Version](https://img.shields.io/github/package-json/v/MxCorpIn/blogs)](https://github.com/MxCorpIn/blogs/blob/main/package.json)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/MxCorpIn/blogs/blob/main/CONTRIBUTING.md)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/MxCorpIn/blogs/blob/main/LICENSE)

**Live demo:** [blog.ossium.in](https://blog.ossium.in)
**Live site:** [blog.ossium.in](https://blog.ossium.in) ·
**Main product:** [ossium.in](https://ossium.in) ·
**Contribute:** [CONTRIBUTING.md](CONTRIBUTING.md) ·
**Issues:** [open an issue](https://github.com/MxCorpIn/blogs/issues)

## Overview
![ossium Blog — guides and Q&A for open-source contributors](public/demo/oss_landingpage.webp)

A fast, static-friendly blog built with Next.js (App Router) and Tailwind CSS, powered by Markdown. Posts live in `content/posts/` as plain Markdown files with YAML frontmatter- no CMS, no database.
## Table of contents

- [Why ossium?](#why-ossium)
- [Features](#features)
- [Screenshots](#screenshots)
- [Tech stack](#tech-stack)
- [Quickstart](#quickstart)
- [Writing posts](#writing-posts)
- [Project structure](#project-structure)
- [Contributing](#contributing)
- [License](#license)
- [Support](#support)

## Why ossium?

Generic dev blogs teach syntax. ossium teaches **getting merged**: finding the
right issue, writing a reviewable PR, and navigating programs like GSoC and
Hacktoberfest.

| If you use… | You get… | With ossium you get… |
| --------------------- | ------------------------------------------ | ----------------------------------------------------- |
| Medium / Dev.to posts | One-off tutorials, paywalls, mixed quality | A curated path: beginner → first PR → GSoC-ready |
| Official program docs | Complete but dense reference material | Opinionated, step-by-step playbooks with examples |
| Generic SEO roundups | “Top 10 tools” with no workflow | Workflows tied to real contributor tasks and tools |
| A from-scratch blog | Weeks of CMS, SEO, and theme setup | Markdown-first SSG with search, SEO, and RSS built in |

## Features

- **Markdown-first content** - every post is a `.md` file with YAML frontmatter
- **Static generation (SSG)** - all post pages pre-rendered at build time for fast loads and strong SEO
- **Search + filters** - client-side search across title, description, tags, and keywords, with type (`article` / `guide` / `how-to` / `Q&A`) and category filters
- **Featured rail** - a sticky "Featured" column on the listing page
- **Light/dark theme** - dark by default, with a persisted, flash-free toggle
- **SEO out of the box** - per-post metadata, JSON-LD (`Blog`, `FAQ` for `question` posts), `sitemap.xml`, `robots.txt`, and an RSS 2.0 feed
- **Reading time** - estimated from the Markdown body (~200 wpm)
- **Related posts** - ranked by category, type, and shared tags
**Write in Markdown, ship a fast site.**

- 📝 **Markdown-first** — every post is a `.md` file with typed YAML
frontmatter. No CMS, no database.
- ⚡ **Static generation** — all pages pre-rendered at build time for fast
loads and strong SEO.
- 🔍 **Search + filters** — instant client-side search across titles, tags,
and keywords, with `article` / `guide` / `howto` / `question` and category
filters.
- ⭐ **Featured rail** — sticky spotlight column for must-read posts.
- 🌓 **Light/dark theme** — dark by default, persisted, flash-free toggle.
- 📈 **SEO out of the box** — per-post metadata, `Blog` + `FAQ` JSON-LD,
`sitemap.xml`, `robots.txt`, and an RSS 2.0 feed (`/feed.xml`).
- ⏱️ **Reading time + related posts** — ~200 wpm estimates and ranking by
category, type, and shared tags.
- 🖼️ **Galleries + code windows** — `:::gallery` directive for responsive
image grids, captioned figures, and syntax-highlighted code blocks.

## Screenshots

| Landing | Dashboard |
| ------------------------------------------------------ | ----------------------------------------------------------------------------- |
| ![Blog landing page](public/demo/oss_landingpage.webp) | ![Contributor dashboard](public/demo/oss_dashboardpage.webp) |
| Search, filters, and the featured rail. | Where readers put the guides into practice on [ossium.in](https://ossium.in). |

Open Graph preview (`/demo/oss_og-toposspage.png`) powers link unfurls on
social and chat apps.

## Tech stack

| Layer | Choice |
| --------------- | ------------------------------------------------------------------------------------------------------------------- |
| Framework | [Next.js](https://nextjs.org) 15 (App Router) |
| UI | [React](https://react.dev) 19 + [Tailwind CSS](https://tailwindcss.com) v4 |
| Content | Markdown + YAML frontmatter (`content/posts/`) |
| Rendering | [react-markdown](https://github.com/remarkjs/react-markdown) + [remark-gfm](https://github.com/remarkjs/remark-gfm) |
| Fonts | Inter (body), General Sans (headings), JetBrains Mono (code) - loaded from CDN |
| Language | TypeScript (strict) |
| Package manager | pnpm |
| Layer | Choice |
| --------------- | --------------------------------------------------------------------------------------------------- |
| Framework | [Next.js](https://nextjs.org) 16 (App Router, SSG) |
| UI | [React](https://react.dev) 19 + [Tailwind CSS](https://tailwindcss.com) v4 |
| Content | Markdown + YAML frontmatter (`content/posts/`) |
| Rendering | Server-side [unified](https://unifiedjs.com) pipeline (`remark`/`rehype`) + `:::gallery` directives |
| Fonts | Inter (body), General Sans (headings), JetBrains Mono (code) via CDN |
| Language | TypeScript (strict) |
| Package manager | [pnpm](https://pnpm.io) 11.15.1 (via `packageManager` + Corepack) |

How a post becomes a page:

```mermaid
flowchart LR
A["content/posts/*.md"] --> B["unified: remark-parse, remark-gfm, directives"]
B --> C["rehype-highlight + post-process"]
C --> D["Static HTML at build time"]
D --> E["/:slug + sitemap + RSS"]
```

## Getting started
## Quickstart

### Prerequisites

- **Node.js 20+** (see `engines` in `package.json`)
- **pnpm 8+** - the repo pins `pnpm@11.15.1` via `packageManager`; enable it with `corepack enable` if you use Corepack
- **pnpm 11+** — `corepack enable` activates the pinned `pnpm@11.15.1`

### 1. Clone the repo
### Run it locally

```bash
git clone https://github.com/MxCorpIn/blogs.git
cd ossium-blog
```

### 2. Install dependencies

```bash
cd blogs
pnpm install
```

### 3. Configure environment variables

```bash
cp .env.example .env
```

| Variable | Description |
| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `NEXT_PUBLIC_APP_URL` | Public base URL of the site. Used for canonical URLs, RSS links, sitemap, and OG image URLs. Use `http://localhost:3000` locally and your deployed domain (e.g. `https://blog.ossium.in`) in production. |

See [.env.example](.env.example) for the complete list with inline comments.

### 4. Start the dev server

```bash
pnpm dev
```

Open <http://localhost:3000>.

### 5. Build for production
| Variable | What it does |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `NEXT_PUBLIC_APP_URL` | Base URL for canonical links, sitemap, RSS, and OG images. `http://localhost:3000` locally, `https://blog.ossium.in` in production. |

See [.env.example](.env.example) for the annotated list.

### Build for production

```bash
pnpm build && pnpm start
```

## Folder structure
### Verify before you push

```
ossium-blog/
├── app/ # Next.js App Router - pages, layouts, SEO routes
│ ├── [slug]/page.tsx # Individual post pages (SSG via generateStaticParams)
│ ├── BlogListing.tsx # Client component: search, filters, featured rail
│ ├── feed.xml/route.ts # RSS 2.0 feed
│ ├── sitemap.ts # Sitemap (listing + every post)
│ ├── robots.ts # robots.txt
│ └── layout.tsx # Root layout (theme, metadata, fonts)
├── components/ # React components
│ ├── blog/ # PostCard, MarkdownBody, ShareButton
│ ├── landing/ # Footer, DashedFrame
│ ├── theme/ # ThemeToggle
│ └── ui/ # Container
├── content/posts/ # Blog posts - Markdown + YAML frontmatter
├── lib/
│ ├── content/ # Frontmatter parser, post loading, related posts
│ ├── constants.ts # APP_URL, APP_CONFIG, SOURCE_EDIT_BASE
│ └── utils.ts # cn() classname helper
├── public/ # Static assets (logos, demo images)
├── .github/ # Issue/PR templates, CI workflow, FUNDING
└── next.config.ts # Next.js config (security headers, image caching)
```bash
pnpm lint && pnpm typecheck && pnpm format:check && pnpm test && pnpm build
```

## Writing posts

1. Create `content/posts/your-slug.md` (the slug is the filename without `.md`).
2. Add YAML frontmatter (see [content/posts/README.md](content/posts/README.md) for the full schema).
3. Write the body in Markdown.
4. Visit `/{slug}` locally - the sitemap and RSS feed pick up published posts automatically.
1. Create `content/posts/your-slug.md` — the filename is the URL.
2. Add frontmatter (full schema: [content/posts/README.md](content/posts/README.md)).
3. Write Markdown — galleries via `:::gallery columns=3`, captions via image
alt text.
4. Preview at `/{slug}` — sitemap and RSS pick up published posts automatically.

```yaml
---
title: "Clear, keyword-aware title"
description: "12 sentences for SEO meta and cards (~150160 chars ideal)."
description: "1-2 sentences for SEO meta and cards (~150-160 chars ideal)."
type: article | guide | howto | question
category: contribution | gsoc | github | career | tools | programs | beginners
tags: [tag-one, tag-two]
Expand All @@ -134,23 +160,58 @@ answerSummary: "Only for type=question - short answer for FAQ rich results."
---
```

Set `draft: true` to hide a post from production until it's ready.
Set `draft: true` to keep a post out of production until it is ready.

## Project structure

```
blogs/
├── app/ # App Router pages, layouts, SEO routes
│ ├── [slug]/page.tsx # Post pages (SSG via generateStaticParams)
│ ├── BlogListing.tsx # Search, filters, featured rail
│ ├── feed.xml/ # RSS 2.0 feed
│ ├── sitemap.ts # Sitemap (listing + every post)
│ ├── robots.ts # robots.txt
│ └── layout.tsx # Theme, metadata, fonts
├── components/blog/ # PostCard, MarkdownBody, ShareButton
├── components/landing/ # Navbar, Footer, DashedFrame
├── components/theme/ # ThemeToggle
├── content/posts/ # Markdown posts + frontmatter schema README
├── lib/content/ # Loading, parsing, related posts, types
├── lib/markdown/ # :::gallery directives + server renderer
└── public/demo/ # Landing, dashboard, and OG preview images
```

## Contributing

Contributions are welcome - content corrections, new posts, and code improvements all count. Please read [CONTRIBUTING.md](CONTRIBUTING.md) first for branch naming, commit message format, and the PR checklist. All community interaction is governed by our [Code of Conduct](CODE_OF_CONDUCT.md).
Code, content, and docs all count. Start with
[CONTRIBUTING.md](CONTRIBUTING.md) — branch naming, Conventional Commits, and
the PR checklist. All interaction follows the
[Code of Conduct](CODE_OF_CONDUCT.md).

Thanks to everyone who has contributed content, code, and support in issues, pull requests, and discussions:
| Way to help | Example |
| ----------- | -------------------------------------------- |
| ✍️ Content | Fix a typo, update a stale guide, add a post |
| 💻 Code | Search, SEO, performance, accessibility, DX |
| 🧭 Triage | Reproduce bugs, answer questions, review PRs |
| 📚 Docs | Clarify setup, improve this README |

<a href="https://github.com/mxcorpin/blogs/graphs/contributors">
<img src="https://contrib.rocks/image?repo=mxcorpin/blogs&max=400&columns=20" />
Thanks to everyone who has contributed code, content, and reviews:

<a href="https://github.com/MxCorpIn/blogs/graphs/contributors">
<img src="https://contrib.rocks/image?repo=MxCorpIn/blogs&max=400&columns=20" alt="Contributors" />
</a>

## License

- **Code** (everything under `app/`, `components/`, `lib/`, and config files) - [MIT License](LICENSE)
- **Content** (everything under `content/posts/`) - Copyright © 2026 Ossium. All rights reserved. Do not republish blog posts without permission.
- **Code** (`app/`, `components/`, `lib/`, configs) — [MIT License](LICENSE)
- **Content** (`content/posts/`) — © Ossium, all rights reserved. Do not
republish posts without permission.

See [CHANGELOG.md](CHANGELOG.md) for release history.

## Support

Questions or content corrections? Email [help@ossium.in](mailto:help@ossium.in) or open a [GitHub issue](https://github.com/MxCorpIn/blogs/issues).
- 📧 Email [help@ossium.in](mailto:help@ossium.in)
- 🐛 [Open an issue](https://github.com/MxCorpIn/blogs/issues)
- 🔒 Security issues: see [SECURITY.md](SECURITY.md)
Loading