Your thoughts, published beautifully
A modern, fast, markdown-based site engine built with ASP.NET Core 9.0. QuillKit combines the simplicity of markdown with the power of a dynamic web application, featuring flexible theming and hybrid content storage.
- π Markdown-First: Write your content in markdown with front matter support
- π¨ Dynamic Theming: Flexible theme system with view location expansion
- π Hybrid Storage: Local files or Azure Blob Storage
- π± Responsive Design: Beautiful, mobile-first Bootstrap 5.3 interface
- π Social Integration: Built-in social media links with brand-accurate styling
- πΌοΈ Media Support: Lightbox galleries and video embed support
- π Clean URLs: SEO-friendly routing and navigation
- Framework: ASP.NET Core 9.0 (MVC)
- UI: Bootstrap 5.3.8 + Bootstrap Icons 1.13.1
- Configuration: YAML with YamlDotNet
- Markdown: Markdig parser with extensions
- Storage: Hybrid (Local files or Azure Blob Storage)
- Caching: In-memory with file watching
Clone the repository and run:
git clone https://github.com/RazorAnt/QuillKit.git
cd QuillKit
dotnet runVisit http://localhost:5000 to see your site and http://localhost:5000/admin for the admin panel.
QuillKit uses two main configuration approaches:
These files control how QuillKit runs:
Development (appsettings.Development.json):
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"ContentProvider": "Local",
"ConnectionStrings": {
"AzureStorage": ""
},
"SiteConfig": {
"BaseUrl": "http://localhost:5000"
},
"AdminAuth": {
"Username": "admin",
"PasswordHash": "240be518fabd2724ddb6f04eeb1da5967448d7e831c08c8fa822809f74c720a9"
}
}Production (appsettings.Production.json - optional, use Azure App Settings instead):
{
"ContentProvider": "AzureBlob",
"ConnectionStrings": {
"AzureStorage": "DefaultEndpointsProtocol=https;AccountName=...;AccountKey=..."
},
"SiteConfig": {
"BaseUrl": "https://quillkit.mydomain.com"
},
"AdminAuth": {
"Username": "admin",
"PasswordHash": "your-sha256-hash-here"
}
}| Setting | Description | Example |
|---|---|---|
ContentProvider |
Where to store content: Local or AzureBlob |
"Local" or "AzureBlob" |
ConnectionStrings:AzureStorage |
Azure Storage connection string (required if using AzureBlob) | "DefaultEndpointsProtocol=https;..." |
SiteConfig:BaseUrl |
Your site's public web address | "https://myblog.com" or "http://localhost:5000" |
AdminAuth:Username |
Admin username | "admin" |
AdminAuth:PasswordHash |
SHA256 hash of admin password | See below |
- Go to SHA256 Hash Generator
- Enter your desired password
- Copy the SHA256 hash
- Paste into
AdminAuth:PasswordHash
Default credentials (for testing):
- Username:
admin - Password:
admin123 - Hash:
240be518fabd2724ddb6f04eeb1da5967448d7e831c08c8fa822809f74c720a9
This YAML file defines your site's appearance and content:
site:
title: "Your Site Title"
subtitle: "Your tagline"
description: "Site description for SEO"
author:
name: "Your Name"
bio: "Your bio"
email: "your@email.com"
social:
github: "your-username"
twitter: "your-handle"
linkedin: "your-handle"
navigation:
- title: "Home"
url: "/"
- title: "About"
url: "/about"
- title: "Archive"
url: "/archive"Edit this file through the admin panel or directly in your text editor to customize your site's branding, navigation, and metadata.
Access the admin dashboard at /admin with your configured credentials:
- Dashboard: View site statistics and recent posts
- Backup Data: Download a zip file with all your data
- Editor: Create and edit posts and pages
- Media: Manage images and media files
- Settings: Edit site configuration
QuillKit uses markdown files with YAML front matter for all posts and pages. Front matter defines metadata about your content.
You can write content in two ways:
- Web Editor: Use the admin dashboard to create and edit posts directly in your browser
- Local Editor: Write in your favorite markdown editor (Obsidian for me) and upload
.mdfiles through the admin panel
Every post or page starts with a YAML front matter block:
---
title: "Your Post Title"
author: "Your Name"
type: "Post"
date: 2025-10-20T14:30:00.0000000
slug: "your-post-slug"
status: "Published"
categories:
- "Category One"
- "Category Two"
tags:
- "tag1"
- "tag2"
description: "Brief description for SEO and previews"
excerpt: "Custom excerpt shown on the homepage"
image: "/media/featured-image.jpg"
link: "https://example.com"
---
Your markdown content goes here...| Field | Required | Type | Description |
|---|---|---|---|
title |
β Yes | String | The title of your post or page |
author |
β No | String | Author name |
type |
β No | String | Post or Page (default: Post) |
date |
β Yes | DateTime | Publication date (YYYY-MM-DDTHH:MM:SS.0000000) |
slug |
β Yes | String | URL-friendly identifier (e.g., my-awesome-post) |
status |
β No | String | Published or Draft (default: Draft) |
categories |
β No | List | Content categories (YAML list format) |
tags |
β No | List | Content tags (YAML list format) |
description |
β No | String | Meta description for SEO |
excerpt |
β No | String | Custom excerpt (overrides auto-generated) |
image |
β No | String | Featured image URL (absolute or relative path) |
link |
β No | String | External link URL (for link posts) |
Minimal Post:
---
title: "Quick Thought"
author: "Al Nyveldt"
slug: "quick-thought"
status: "Published"
---
Just a simple post with the essentials.Full-Featured Post:
---
title: "Getting Started with QuillKit"
author: "Al Nyveldt"
type: "Post"
date: 2025-10-20T09:00:00.0000000
slug: "getting-started-quillkit"
status: "Published"
categories:
- "Blogging"
- "Tutorials"
tags:
- "quillkit"
- "markdown"
- "getting-started"
description: "Learn how to set up and use QuillKit for your blog"
excerpt: "A comprehensive guide to getting started with QuillKit"
image: "/media/quillkit-intro.jpg"
---
Your detailed markdown content...- Field Order: Doesn't matterβorganize however you prefer
- Optional Fields: Can be omitted entirely if not needed
- Empty Fields: Can be left blank (
image:) - Relative Paths: Use
/media/image.jpgfor files in your Content/media folder - Auto-Excerpt: If you don't provide an excerpt, QuillKit will generate one from your content
QuillKit features a powerful and flexible theming system that lets you customize the look and feel of your site without touching the core code.
The theming system uses a cascading view override approach:
- Check
Content/Theme/Viewsfor custom views (highest priority) - Fall back to default views in
/Views(default implementation) - Include theme assets from
Content/Theme/assets
This means you can override just the files you want to customize, and everything else will use sensible defaults.
Content/Theme/
βββ Views/ # Override any view
β βββ Shared/
β β βββ _Layout.cshtml # Custom site layout
β β βββ _Sidebar.cshtml # Custom sidebar
β βββ Site/
β βββ Index.cshtml # Homepage
β βββ Post.cshtml # Post detail
β βββ Page.cshtml # Page detail
βββ assets/ # Theme-specific assets
βββ css/
β βββ theme.css # Custom stylesheets
βββ js/
βββ theme.js # Custom scripts
- Create your theme folder in
Content/Theme - Copy default views from
/Viewsthat you want to customize - Modify the HTML/CSS to match your design
- Add custom assets (CSS, JavaScript, images) to
assets/ - Reference your assets in views with paths like
/theme-assets/css/theme.css
The default Bootstrap 5.3 styling will still apply to any views you don't override, giving you a solid foundation to build upon.
QuillKit is designed for easy deployment to Azure with full support for cloud storage.
- Deploy your fork as an Azure Web App
- Create an Azure Storage Account for your posts and media files
- Configure Azure App Settings to override local defaults:
ContentProvider:AzureBlobConnectionStrings__AzureStorage: Your storage connection stringAdminAuth__UsernameandAdminAuth__PasswordHash: Your admin credentials
QuillKit respects this configuration hierarchy (highest to lowest):
- Azure App Settings (environment variables)
- appsettings.Production.json (if included in deployment)
- appsettings.json (defaults)
This ensures your secrets stay safe in Azure and never touch version control.