Toodle.PageOptimizer 1.2.1

dotnet add package Toodle.PageOptimizer --version 1.2.1
                    
NuGet\Install-Package Toodle.PageOptimizer -Version 1.2.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Toodle.PageOptimizer" Version="1.2.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Toodle.PageOptimizer" Version="1.2.1" />
                    
Directory.Packages.props
<PackageReference Include="Toodle.PageOptimizer" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Toodle.PageOptimizer --version 1.2.1
                    
#r "nuget: Toodle.PageOptimizer, 1.2.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Toodle.PageOptimizer@1.2.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Toodle.PageOptimizer&version=1.2.1
                    
Install as a Cake Addin
#tool nuget:?package=Toodle.PageOptimizer&version=1.2.1
                    
Install as a Cake Tool

Toodle.PageOptimizer

NuGet Version NuGet Downloads

A high-performance metadata, breadcrumb, and resource optimization manager for ASP.NET Core. It streamlines SEO best practices and improves Core Web Vitals (LCP/FCP) by automating resource hinting and header management.

See https://www.pricewatchdog.co.uk and https://www.competitions-whale.co.uk as examples of websites using this library.

Features

  • Fluent SEO API: Easily manage Meta Titles, Descriptions, and Canonical URLs.
  • HTTP Link Headers: Injects rel=preload and rel=preconnect headers into the HTTP response for faster asset discovery.
  • Static File Caching: Granular control over Cache-Control headers for specific file extensions or paths.
  • HTTPS Compression: One-click setup for Brotli and Gzip.
  • Structured Data: Automatic generation of JSON-LD BreadcrumbList for Google Search results.
  • Flexible Sitemaps: Register dynamic sitemap sources from databases or static lists.
  • Localization: Integrated support for RequestCulture and og:locale tags.

Installation

dotnet add package Toodle.PageOptimizer

Service Configuration

Register the service in Program.cs. This is where you define your compression and sitemap logic.

builder.Services.AddPageOptimizer(options =>
{
    options.EnableHttpsCompression = true; // Enables Brotli/Gzip for HTTPS
    options.UseRequestCulture = new RequestCulture("en-GB");
})
.AddSitemapSource(async (serviceProvider) =>
{
    // Example: Fetching dynamic product links for the sitemap
    using var scope = serviceProvider.CreateScope();
    var db = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
    var products = await db.Products.ToListAsync();

    return products.Select(p => new SitemapUrl {
        Location = $"/products/{p.Slug}",
        Priority = 0.8m,
        ChangeFrequency = ChangeFrequency.Weekly
    });
});

Middleware & App Configuration

Configure your global site defaults. This locks the global configuration to prevent accidental runtime changes.

app.ConfigurePageOptimizer()
    .WithBaseTitle("Price Watchdog", "|")
    .WithBaseUrl("https://www.pricewatchdog.co.uk")
    .AddDefaultPreconnect("https://res.cloudinary.com")
    // Adds Link: </js/bundle.js>; rel=preload; as=script to every GET response header
    .AddDefaultPreload("/js/bundle.min.js", AssetType.Script) 
    .AddDefaultBreadcrumb("Home", "/")
    .AddStaticFileCacheHeaders(opt =>
    {
        opt.IsPublic = true;
        opt.MaxAge = TimeSpan.FromDays(7);
        opt.FileExtensions = new[] { ".js", ".css", ".ico", ".webp" };
    })
    .ServeSitemap(opt =>
    {
        opt.Path = "/sitemap.xml";
        opt.CacheDuration = TimeSpan.FromHours(4);
    });

app.UsePageOptimizer(); // Enables header injection and SEO middleware

Rendering Meta Tags & Breadcrumbs

Add the following to your _ViewImports.cshtml:

@addTagHelper *, Toodle.PageOptimizer

In Layout (_Layout.cshtml)

The <page-optimizer /> tag helper handles the title, meta, link rel="canonical", and the JSON-LD Breadcrumb script.

<head>
    <meta charset="utf-8" />
    <page-optimizer />
</head>

UI Breadcrumbs (Partial View)

Create a partial view (e.g., _Breadcrumbs.cshtml) to render the visual navigation using the injected service.

@inject Toodle.PageOptimizer.IPageOptimizerService pageOptimizerService
@{
    var breadcrumbs = pageOptimizerService.GetBreadCrumbs();
}

@if (breadcrumbs.Any())
{
    <nav aria-label="breadcrumb">
        <ol class="breadcrumb">
            @foreach (var crumb in breadcrumbs)
            {
                var isLast = breadcrumbs.Last() == crumb;
                <li class="breadcrumb-item @(isLast ? "active" : "")">
                    @if (isLast)
                    {
                        <span aria-current="page">@crumb.Title</span>
                    }
                    else
                    {
                        <a href="@crumb.Url">@crumb.Title</a>
                    }
                </li>
            }
        </ol>
    </nav>
}

Controller Usage

Update page metadata and breadcrumbs dynamically within your actions.


public class ProductController : Controller
{
    private readonly IPageOptimizerService _optimizer;

    public ProductController(IPageOptimizerService optimizer)
    {
        _optimizer = optimizer;
    }

    public IActionResult Details(string slug)
    {
        var product = _db.Products.Find(slug);

        _optimizer
            .SetMetaTitle(product.Name)
            .SetMetaDescription(product.Summary)
            .SetCanonicalUrl($"/products/{product.Slug}")
            .AddBreadCrumb("Products", "/products")
            .AddBreadCrumb(product.Name); // Current page (no URL)

        // Prevent indexing for specific conditions
        if (product.IsDiscontinued) _optimizer.SetNoIndex();

        return View(product);
    }
}

Advanced Mechanics

The library automatically appends Link headers to the HTTP response for all preconnect and preload resources defined in configuration. This triggers "Early Hints" in supported browsers and CDNs, allowing assets to begin downloading while the server is still processing the HTML.

Response Compression

When EnableHttpsCompression is set to true, the library automatically configures:

  • Brotli & Gzip at Optimal compression levels.
  • Support for image/svg+xml and other standard MIME types.

Static File Cache Middleware

The StaticFileCacheHeaderMiddleware intercepts requests for static assets and applies Cache-Control headers based on your FileExtensions and Paths configuration, ensuring high cache hit ratios.

Product 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 is compatible.  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 is compatible.  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 is compatible.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net6.0

    • No dependencies.
  • net7.0

    • No dependencies.
  • net8.0

    • No dependencies.
  • net9.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.2.1 108 1/14/2026
1.2.0 239 9/30/2025
1.1.0 255 2/27/2025
1.0.0 187 2/19/2025