![]() |
VOOZH | about |
dotnet add package OutWit.Web.Framework --version 1.4.1
NuGet\Install-Package OutWit.Web.Framework -Version 1.4.1
<PackageReference Include="OutWit.Web.Framework" Version="1.4.1" />
<PackageVersion Include="OutWit.Web.Framework" Version="1.4.1" />Directory.Packages.props
<PackageReference Include="OutWit.Web.Framework" />Project file
paket add OutWit.Web.Framework --version 1.4.1
#r "nuget: OutWit.Web.Framework, 1.4.1"
#:package OutWit.Web.Framework@1.4.1
#addin nuget:?package=OutWit.Web.Framework&version=1.4.1Install as a Cake Addin
#tool nuget:?package=OutWit.Web.Framework&version=1.4.1Install as a Cake Tool
Part of WitDocs � a Blazor WebAssembly framework for building content-driven static websites with markdown-based content management, SEO optimization, and automatic content generation.
dotnet add package OutWit.Web.Framework
<ProjectReference Include="path/to/OutWit.Web.Framework.csproj" />
your-site/
Pages/ # Thin page wrappers
wwwroot/
content/ # Markdown content
blog/
projects/
articles/
docs/
css/
theme.css # Your color scheme
site.css # Site-specific styles
images/
site.config.json
Program.cs
YourSite.csproj
Create wwwroot/site.config.json:
{
"siteName": "My Site",
"baseUrl": "https://example.com",
"logo": "/images/logo.svg",
"defaultTheme": "dark",
"navigation": [
{ "title": "Home", "href": "/" },
{ "title": "Blog", "href": "/blog" },
{ "title": "Contact", "href": "/contact" }
],
"footer": {
"copyright": "Your Name",
"socialLinks": [
{ "platform": "github", "url": "https://github.com/you" }
]
},
"seo": {
"defaultImage": "/images/social-card.png",
"twitterHandle": "@yourhandle"
}
}
Create wwwroot/css/theme.css:
:root {
--color-background: #ffffff;
--color-text-primary: #333333;
--color-accent: #007CF0;
/* ... other variables */
}
[data-theme="dark"] {
--color-background: #1f1f1f;
--color-text-primary: #d1d1d1;
--color-accent: #00a3ff;
}
@* Pages/Index.razor *@
@page "/"
@using OutWit.Web.Framework.Components.Pages
<HomePage />
@* Pages/Blog.razor *@
@page "/blog"
@using OutWit.Web.Framework.Components.Pages
<BlogListPage />
@* Pages/BlogPost.razor *@
@page "/blog/{Slug}"
@using OutWit.Web.Framework.Components.Pages
<BlogPostPage Slug="@Slug" />
@code {
[Parameter] public string Slug { get; set; } = "";
}
---
title: 'My Blog Post'
description: 'Short description for SEO'
summary: |
Longer summary with **markdown** support
tags: [blazor, dotnet, web]
publishDate: 2024-01-15
menuTitle: 'Short Title' # Optional: short title for navigation menus
showInMenu: true # Show in dropdown menus (default: true)
showInHeader: false # Show as top-level nav item (projects only)
---
# Content starts here
Your markdown content...
wwwroot/content/
index.json # Auto-generated manifest
blog/
2024-01-15-post-title.md
projects/
01-project-name/
index.md
image.png
articles/
my-article.md
docs/
getting-started.md
| Component | Route | Description |
|---|---|---|
| HomePage | / | Home page with hero and projects |
| BlogListPage | /blog | Blog listing with search |
| BlogPostPage | /blog/{slug} | Individual blog post |
| ProjectPage | /project/{slug} | Project detail page |
| ArticlePage | /article/{slug} | Article with TOC |
| DocsPage | /docs/{slug} | Documentation page |
| SearchPage | /search | Search results |
| ContactPage | /contact | Contact form |
| NotFoundPage | * | 404 page |
You can embed components directly in markdown content using [[Name ...]] syntax.
The framework ships built-in components (YouTube, Svg, FloatingImage), and
you can register your own without modifying the framework.
[Parameter]s (parameters
are supplied as strings from the markdown attributes; block components also
receive InnerContent and BasePath):@* PricingTable.razor *@
<div class="pricing pricing--@Plan">...</div>
@code {
[Parameter] public string Plan { get; set; } = "free";
}
Program.cs after AddOutWitWebFramework():builder.Services.AddOutWitWebFramework();
builder.Services.AddContentComponent<PricingTable>("Pricing");
Here are our plans:
[[Pricing plan="pro"]]
Block (wrapper) syntax with inner content is also supported:
[[Note type="warning"]]
This is important.
[[/Note]]
Static site generation: embedded components can't be rendered to static HTML at build time, so the generator degrades them gracefully for crawlers — block components keep their inner content (still indexed), self-closing components are omitted. The live Blazor app renders the real component after hydration.
<PropertyGroup>
<OutWitGenerateContent>true</OutWitGenerateContent>
<OutWitGenerateInDebug>true</OutWitGenerateInDebug>
<OutWitGenerateStaticPages>true</OutWitGenerateStaticPages>
<OutWitGenerateSearchIndex>true</OutWitGenerateSearchIndex>
<OutWitGenerateRssFeed>true</OutWitGenerateRssFeed>
<OutWitGenerateOgImages>false</OutWitGenerateOgImages>
<OutWitHostingProvider>cloudflare</OutWitHostingProvider>
</PropertyGroup>
For faster development experience, enable content generation in Debug mode:
<PropertyGroup>
<OutWitGenerateInDebug>true</OutWitGenerateInDebug>
</PropertyGroup>
This generates navigation and metadata indices during Debug builds, providing:
Without this option, the framework falls back to loading content directly (slower but works).
On Release build, the framework automatically runs the tool to generate:
content/index.json - Content manifestnavigation-index.json - Pre-built navigation menu data (v1.2.0+)content-metadata.json - Pre-built content metadata for lists (NEW in v1.3.0)sitemap.xml - SEO sitemaprobots.txt - Crawler rulessearch-index.json - Pre-built search indexfeed.xml - RSS feed for blog*/index.html - Static HTML pages for SEO_headers, _redirects - Hosting provider configPrerequisite: Install the Generator tool globally:
dotnet tool install -g OutWit.Web.Generator
Then simply build in Release mode:
dotnet build -c Release
outwit-generate \
--content-path ./wwwroot/content \
--output-path ./wwwroot \
--site-url https://example.com \
--site-name "My Site"
For OG images (requires Playwright):
npx playwright install chromium
outwit-generate --content-path ./wwwroot/content --output-path ./wwwroot
The framework generates a navigation-index.json file containing pre-built menu data. This eliminates the need to parse all markdown files when loading the header navigation, resulting in significantly faster page loads for sites with many content items.
The framework now generates a content-metadata.json file containing lightweight metadata for all content items. This allows list pages (HomePage, BlogListPage) to render instantly without parsing individual markdown files.
Before v1.3.0: List pages loaded and parsed ALL markdown files to display titles, descriptions, and tags
After v1.3.0: List pages load a single small JSON file with pre-extracted metadata
The content metadata index includes:
During development (when the metadata index is not available), the framework falls back to loading content directly.
The framework can generate social media preview images (1200x630 PNG) for each content page.
Colors are automatically read from your theme.css:
--color-accent - Accent color for highlights--color-background - Background colorTo enable in build:
<OutWitGenerateOgImages>true</OutWitGenerateOgImages>
Requires Playwright:
npm install -D playwright
npx playwright install chromium
| Service | Description |
|---|---|
| ContentService | Load and parse markdown content |
| ConfigService | Load site configuration |
| NavigationService | Load pre-built navigation index (v1.2.0+) |
| ContentMetadataService | Load pre-built content metadata (NEW in v1.3.0) |
| SearchService | Full-text search with pre-built index |
| MarkdownService | Parse markdown to HTML |
| ThemeService | Theme switching (light/dark) |
- name: Build
run: dotnet publish -c Release
- name: Deploy
uses: cloudflare/pages-action@v1
with:
directory: publish/wwwroot
name: Build and Deploy
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.0.x'
- name: Build
run: dotnet publish -c Release -o publish
- name: Deploy to Cloudflare Pages
uses: cloudflare/pages-action@v1
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
projectName: your-site
directory: publish/wwwroot
Licensed under the Apache License, Version 2.0. See LICENSE.
If you use WitDocs in a product, a mention is appreciated (but not required), for example: "Built with WitDocs".
"WitDocs" and "OutWit" are used to identify the official project by Dmitry Ratner.
You may:
You may not:
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 net10.0 is compatible. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
This package is not used by any NuGet packages.
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.4.1 | 98 | 6/15/2026 |
| 1.4.0 | 96 | 6/15/2026 |
| 1.3.5 | 91 | 6/15/2026 |
| 1.3.4 | 133 | 2/5/2026 |
| 1.3.3 | 116 | 2/5/2026 |
| 1.3.2 | 119 | 2/3/2026 |
| 1.3.1 | 129 | 2/2/2026 |
| 1.3.0 | 133 | 2/2/2026 |
| 1.1.12 | 123 | 1/25/2026 |
| 1.1.11 | 127 | 1/24/2026 |
| 1.1.10 | 126 | 1/24/2026 |
| 1.1.9 | 127 | 1/23/2026 |
| 1.1.8 | 116 | 1/23/2026 |
| 1.1.7 | 120 | 1/18/2026 |
| 1.1.6 | 120 | 1/17/2026 |
| 1.1.5 | 118 | 1/17/2026 |
| 1.1.4 | 122 | 1/17/2026 |
| 1.1.3 | 119 | 1/17/2026 |
| 1.1.2 | 125 | 1/17/2026 |
| 1.1.1 | 117 | 1/14/2026 |