Getting Started
Get Contento CMS up and running in under five minutes.
Contento is an open-source content management system built on .NET 10 and PostgreSQL. It ships as a traditional server-rendered admin panel and a fully featured headless JSON API, so you can power any front end — a Next.js app, a static site generator, a mobile app, or the built-in themed blog.
Key highlights:
- Markdown-first editor with live preview and autosave
- Full REST API with public content delivery and authenticated management endpoints
- Theme system with CSS variables and 8 built-in themes
- Plugin system powered by a sandboxed JavaScript engine (Jint)
- WordPress and Markdown import/export
- Full-text search with PostgreSQL
ts_vector - Threaded comments with honeypot spam protection
- Media library with image, PDF, and video support
- Hierarchical categories and tag-based taxonomy
- Audit log for tracking all content changes
- Newsletter management with subscriber signup and campaign editor
- Stripe-powered membership with plans, content gating, and billing portal
- Multi-site support with domain-based routing
- Task scheduler with cron-based automation
- Custom post types with JSON field schemas
- SEO service with JSON-LD structured data and sitemap generation
- AI-powered content generation and SEO analysis
- Automatic responsive image variants (640w, 1024w, 1536w WebP)
- Spam protection with AI scoring and configurable auto-approve threshold
Prerequisites
| Dependency | Version | Required |
|---|---|---|
| .NET SDK | 10.0 or later | Yes |
| PostgreSQL | 14 or later | Yes |
| Redis | 7.x | Optional (caching) |
| Node.js | 18+ (for Tailwind CSS build) | Optional (development) |
Installation
1. Clone the repository
# Clone via HTTPS git clone https://github.com/plsft/contento.git cd contento
2. Restore dependencies
dotnet restore
3. Configure connection strings
Create an appsettings.Development.json file in the src/Contento.Web directory (or set environment variables):
{
"ConnectionStrings": {
"DefaultConnection": "Host=localhost;Port=5432;Database=contento;Username=postgres;Password=yourpassword"
},
"Contento": {
"ApiSigningKey": "your-secret-key-at-least-32-characters-long"
},
"Redis": {
"ConnectionString": "localhost:6379"
},
"Stripe": {
"SecretKey": "sk_test_...",
"PublishableKey": "pk_test_...",
"WebhookSecret": "whsec_..."
},
"Email": {
"SmtpHost": "smtp.example.com",
"SmtpPort": "587",
"FromAddress": "noreply@yourdomain.com"
}
}
Contento:ApiSigningKey to a strong, unique secret.
The default fallback key is insecure and should never be used in production.
4. Initialize the database
Contento uses Bowtie for automatic schema management. On first run, it creates all tables and seeds default data automatically:
cd src/Contento.Web dotnet run
The application starts at https://localhost:5001 (or http://localhost:5000).
First Steps
1. Log in to the admin panel
Navigate to https://localhost:5001/admin and log in with the default credentials:
| Field | Value |
|---|---|
admin@contento.local |
|
| Password | Admin1234 |
2. Create your first post
- Click Posts in the sidebar, then click New Post.
- Enter a title and write your content in Markdown. The live preview updates as you type.
- Add tags, choose a category, and optionally upload a cover image.
- Click Publish to make the post live.
3. Configure site settings
Go to Settings in the admin sidebar to configure:
- Site name — Displayed in the header, feeds, and metadata
- Tagline — A short description of your site
- Locale — e.g.,
en-US,ja-JP - Timezone — e.g.,
UTC,America/New_York,Asia/Tokyo
4. Choose a theme
Navigate to Themes and activate one of the 8 built-in themes. Each theme sets CSS variables that control fonts, colors, and spacing across the public site.
5. Configure Stripe (optional)
If you want to enable paid memberships, configure your Stripe keys in the environment variables or appsettings.json.
Then navigate to Membership in the admin sidebar to create your first plan.
Project Structure
contento/ |-- src/ | |-- Contento.Core/ # Domain models, interfaces | | |-- Models/ # 17 entity models (Post, User, Theme, Subscriber, ...) | | |-- Interfaces/ # 22 service interfaces | | | |-- Contento.Services/ # Service implementations (23 files) | | | |-- Contento.Plugins/ # Jint-based plugin host | | | |-- Contento.Web/ # ASP.NET 10 web application | | |-- Controllers/ # 21 API controllers (113 endpoints) | | |-- Pages/Admin/ # 21+ Razor admin pages | | |-- Styles/app.css # CSS design system | | | |-- Contento.Tests/ # 428 tests (NUnit + Moq + Bogus) | |-- marketing/ # Marketing site and docs
Environment Variables
Contento reads configuration from appsettings.json, environment variables, and user secrets.
Environment variables follow the __ (double underscore) convention for nested keys.
| Variable | Description | Default |
|---|---|---|
ConnectionStrings__DefaultConnection |
PostgreSQL connection string | Required |
Contento__ApiSigningKey |
HMAC-SHA256 signing key for API tokens | Insecure default |
Redis__ConnectionString |
Redis connection string for caching | Empty (disabled) |
ASPNETCORE_ENVIRONMENT |
Runtime environment | Production |
ASPNETCORE_URLS |
Listening URLs | http://+:5000 |
Serilog__MinimumLevel__Default |
Log level: Verbose, Debug, Information, Warning, Error, Fatal | Information |
Contento__MaxUploadSizeMb |
Maximum media upload size | 10 |
Contento__AllowedOrigins |
Comma-separated CORS origins for headless mode | * |
Stripe__SecretKey |
Stripe API secret key for server-side operations | Empty (disabled) |
Stripe__PublishableKey |
Stripe publishable key for client-side checkout | Empty (disabled) |
Stripe__WebhookSecret |
Stripe webhook signing secret for event verification | Empty |
Email__SmtpHost |
SMTP server hostname for newsletter delivery | Empty (disabled) |
Email__SmtpPort |
SMTP server port | 587 |
Email__FromAddress |
Sender email address for newsletters | Empty |
Next Steps
- Admin Guide — Learn how to manage posts, media, themes, and users
- API Reference — Complete endpoint documentation for headless integrations
- Headless Mode — Build custom frontends with Next.js, 11ty, or any framework
- Plugin Development — Extend Contento with JavaScript plugins
- Theme Development — Create custom themes with CSS variables