Slotty 1.0.2
See the version list below for details.
dotnet add package Slotty --version 1.0.2
NuGet\Install-Package Slotty -Version 1.0.2
<PackageReference Include="Slotty" Version="1.0.2" />
<PackageVersion Include="Slotty" Version="1.0.2" />
<PackageReference Include="Slotty" />
paket add Slotty --version 1.0.2
#r "nuget: Slotty, 1.0.2"
#:package Slotty@1.0.2
#addin nuget:?package=Slotty&version=1.0.2
#tool nuget:?package=Slotty&version=1.0.2
🎯 Slotty
<div align="center">
A modern, flexible content slot system for ASP.NET Core that replaces the limitations of @RenderSection
</div>
🚀 Why Slotty?
Tired of the rigid, error-prone @RenderSection
system? Slotty brings modern content management to ASP.NET Core with a flexible, component-based approach that just works.
The Problem with @RenderSection
// ❌ Old way: Rigid, error-prone, limited
@RenderSection("Scripts", required: false)
@RenderSection("Styles", required: false)
// Must define sections in exact layout hierarchy
// No dynamic content injection
// Poor error handling
// Limited extensibility
The Slotty Solution
<slot name="head"></slot>
<slot name="scripts"></slot>
<slot name="sidebar">
<div>Default sidebar content</div>
</slot>
✨ Features
- 🎯 Multiple Content Sources - Add content to slots from anywhere in your application
- 🔧 Slot Extensions - Automatic
:before
and:after
extension points - 🛡️ Type Safety - Built-in validation with helpful error messages
- 🎨 Development Tools - Visual slot debugging in development mode
- 📦 Zero Configuration - Works out of the box with sensible defaults
- 🚀 High Performance - Request-scoped content management
- 🔄 Backward Compatible - Migrate gradually from
@RenderSection
📋 Table of Contents
- Installation
- Quick Start
- Configuration
- Basic Usage
- Advanced Examples
- Development Tools
- Migration Guide
- API Reference
- Contributing
📦 Installation
Package Manager Console
Install-Package Slotty
.NET CLI
dotnet add package Slotty
PackageReference
<PackageReference Include="Slotty" Version="1.0.0" />
⚡ Quick Start
1. Register Services
// Program.cs
builder.Services.AddSlotty();
app.UseSlotty(); // For automatic dev tools injection
2. Define Slots in Layout
<!DOCTYPE html>
<html>
<head>
<slot name="head">
<title>Default Title</title>
</slot>
</head>
<body>
<header>
<slot name="header"></slot>
</header>
<main>
@RenderBody()
</main>
<slot name="scripts"></slot>
</body>
</html>
3. Fill Slots from Views
<fill slot="head">
<title>Home Page</title>
<meta name="description" content="Welcome to our site">
</fill>
<fill slot="header">
<nav>Navigation content</nav>
</fill>
<h1>Welcome!</h1>
<fill slot="scripts">
<script src="~/js/home.js"></script>
</fill>
⚙️ Configuration
Basic Configuration
// Use default settings (recommended)
builder.Services.AddSlotty();
Advanced Configuration
// Program.cs - Programmatic configuration
builder.Services.AddSlotty(options =>
{
options.ValidationMode = SlottyValidationMode.Log; // Silent, Log, Throw
options.DevToolsInjection = SlottyDevToolsInjectionMode.Auto; // Auto, Always, Never
});
Configuration via appsettings.json
{
"Slotty": {
"ValidationMode": "Log",
"DevToolsInjection": "Auto"
}
}
// Program.cs
builder.Services.AddSlotty(builder.Configuration.GetSection("Slotty"));
Validation Modes
Mode | Description | Use Case |
---|---|---|
Silent |
Basic slot name validation only | Production environments |
Log |
Validation with warning logs | Staging/testing environments |
Throw |
Strict validation with exceptions | Development environments |
📖 Basic Usage
Simple Slots
<slot name="sidebar"></slot>
<fill slot="sidebar">
<div class="widget">Content here</div>
</fill>
Slots with Fallbacks
<slot name="breadcrumbs">
<nav>
<a href="/">Home</a>
</nav>
</slot>
<fill slot="breadcrumbs">
<nav>
<a href="/">Home</a> >
<a href="/products">Products</a> >
<span>iPhone</span>
</nav>
</fill>
Multiple Content Blocks
<fill slot="styles">
<link rel="stylesheet" href="~/css/components.css">
</fill>
<fill slot="styles">
<link rel="stylesheet" href="~/css/page-specific.css">
</fill>
<slot name="styles"></slot>
Slot Extensions
Every slot automatically gets :before
and :after
extension points:
<slot name="content"></slot>
<fill slot="content:before">
<div class="alert">Important notice!</div>
</fill>
<fill slot="content">
<h1>Main Content</h1>
</fill>
<fill slot="content:after">
<div class="related-links">Related: ...</div>
</fill>
🔥 Advanced Examples
Dynamic E-commerce Layout
<!DOCTYPE html>
<html>
<head>
<slot name="head">
<title>My Store</title>
</slot>
<slot name="meta"></slot>
</head>
<body>
<header>
<slot name="header:before"></slot>
<slot name="navigation"></slot>
<slot name="header:after"></slot>
</header>
<div class="container">
<aside>
<slot name="sidebar">
<div>Default sidebar</div>
</slot>
</aside>
<main>
<slot name="content:before"></slot>
@RenderBody()
<slot name="content:after"></slot>
</main>
</div>
<footer>
<slot name="footer"></slot>
</footer>
<slot name="scripts:before"></slot>
<slot name="scripts"></slot>
<slot name="scripts:after"></slot>
</body>
</html>
Product Page with Rich Content
<fill slot="head">
<title>@Model.Name - My Store</title>
</fill>
<fill slot="meta">
<meta name="description" content="@Model.Description">
<meta property="og:title" content="@Model.Name">
<meta property="og:image" content="@Model.ImageUrl">
</fill>
<fill slot="header:before">
<div class="sale-banner">🔥 Flash Sale: 50% Off!</div>
</fill>
<fill slot="navigation">
<nav>
<a href="/">Home</a> >
<a href="/products">Products</a> >
@Model.Category.Name
</nav>
</fill>
<fill slot="sidebar">
<div class="filters">
<h3>Filter Products</h3>
</div>
<div class="recent-products">
<h3>Recently Viewed</h3>
</div>
</fill>
<div class="product-details">
<h1>@Model.Name</h1>
<div class="price">$@Model.Price</div>
</div>
<fill slot="content:after">
<section class="related-products">
<h2>You Might Also Like</h2>
</section>
<section class="reviews">
<h2>Customer Reviews</h2>
</section>
</fill>
<fill slot="scripts">
<script src="~/js/product-gallery.js"></script>
<script src="~/js/add-to-cart.js"></script>
</fill>
Conditional Content with View Components
<fill slot="sidebar:before">
@await Component.InvokeAsync("ShoppingCart")
</fill>
<fill slot="footer">
@if (User.Identity.IsAuthenticated)
{
@await Component.InvokeAsync("UserAccount")
}
else
{
@await Component.InvokeAsync("LoginPrompt")
}
</fill>
Partial Views with Slots
<div class="product-card">
<slot name="product-image">
<img src="@Model.DefaultImage" alt="@Model.Name">
</slot>
<div class="product-info">
<h3>@Model.Name</h3>
<div class="price">$@Model.Price</div>
<slot name="product-actions">
<button class="btn btn-primary">Add to Cart</button>
</slot>
</div>
<slot name="product-badges"></slot>
</div>
@Html.Partial("_ProductCard", product)
<fill slot="product-badges">
@if (product.IsOnSale)
{
<span class="badge sale">SALE</span>
}
</fill>
<fill slot="product-actions">
<button class="btn btn-primary" data-product="@product.Id">
Quick Add - $@product.Price
</button>
<button class="btn btn-secondary">
<i class="heart"></i> Wishlist
</button>
</fill>
🛠️ Development Tools
Automatic Dev Tools
In development mode, Slotty automatically injects visual debugging tools:
<style>
.slotty-slot-wrapper { border: 2px dashed #007bff; margin: 2px; }
.slotty-slot-label { background: #007bff; color: white; font-size: 12px; }
</style>
<script>
// Interactive slot debugging
console.log('Slotty dev tools loaded');
</script>
Head-Safe Debugging
Slots in <head>
use HTML comments for valid markup:
<head>
<title>My Page</title>
<meta charset="utf-8">
</head>
Configuration
// Control dev tools injection
builder.Services.AddSlotty(options =>
{
options.DevToolsInjection = SlottyDevToolsInjectionMode.Always; // Always show
// or SlottyDevToolsInjectionMode.Never; // Never show
// or SlottyDevToolsInjectionMode.Auto; // Development only (default)
});
🔄 Migration Guide
From @RenderSection
Before:
@RenderSection("Scripts", required: false)
@RenderSection("Styles", required: false)
@section Scripts {
<script src="~/js/page.js"></script>
}
@section Styles {
<link rel="stylesheet" href="~/css/page.css">
}
After:
<slot name="scripts"></slot>
<slot name="styles"></slot>
<fill slot="scripts">
<script src="~/js/page.js"></script>
</fill>
<fill slot="styles">
<link rel="stylesheet" href="~/css/page.css">
</fill>
Benefits of Migration
@RenderSection | Slotty | Benefit |
---|---|---|
Single content per section | Multiple fills per slot | ✅ Flexible content composition |
Must be defined in hierarchy | Fill from anywhere | ✅ True component architecture |
Required/optional only | Rich validation modes | ✅ Better error handling |
No extensibility | :before and :after extensions |
✅ Built-in extensibility |
No default content | Fallback content support | ✅ Progressive enhancement |
📚 API Reference
TagHelpers
<slot>
Defines a content slot that can be filled by <fill>
tags.
Attributes:
name
(required): The unique name of the slot
Example:
<slot name="sidebar">
<div>Default content</div>
</slot>
<fill>
Adds content to a named slot.
Attributes:
slot
(required): The name of the slot to fill
Example:
<fill slot="sidebar">
<div>Custom sidebar content</div>
</fill>
Configuration
SlottyOptions
Property | Type | Default | Description |
---|---|---|---|
ValidationMode |
SlottyValidationMode |
Silent |
Validation behavior |
DevToolsInjection |
SlottyDevToolsInjectionMode |
Auto |
Dev tools injection mode |
SlottyValidationMode
Value | Description |
---|---|
Silent |
Basic validation only |
Log |
Validation with warning logs |
Throw |
Strict validation with exceptions |
SlottyDevToolsInjectionMode
Value | Description |
---|---|
Auto |
Inject in development environment only |
Always |
Always inject dev tools |
Never |
Never inject dev tools |
Service Registration
// Basic registration
services.AddSlotty();
// With configuration
services.AddSlotty(options => { /* configure */ });
// From configuration section
services.AddSlotty(configuration.GetSection("Slotty"));
Middleware Registration
// Enable automatic dev tools injection
app.UseSlotty();
🤝 Contributing
We love contributions! Please see our Contributing Guide for details.
Development Setup
git clone https://github.com/AaronLayton/slotty.git
cd slotty
dotnet restore
dotnet build
dotnet test
Running Examples
dotnet run --project Slotty.Example
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
🌟 Support
- ⭐ Star this repo if you find it useful
- 🐛 Report bugs via GitHub Issues
- 💡 Request features via GitHub Discussions
- 📖 Documentation at GitHub Wiki
<div align="center">
Made with ❤️ by Aaron Layton • Follow on X
</div>
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net6.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last Updated |
---|---|---|
1.1.0 | 550 | 7/22/2025 |
1.0.2 | 169 | 7/16/2025 |
0.0.0-alpha.0.4 | 121 | 7/16/2025 |
See CHANGELOG.md for detailed release notes