---
title: Add a Razor landing page at the site root
description: "Route a Razor component at / so a DocSite opens on a hand-built landing page, and swap the doc-page chrome for the sidebar-free FullWidthLayout."
canonical_url: https://usepennington.net/tutorials/docsite/landing-page/
sidecar_url: https://usepennington.net/tutorials/docsite/landing-page.md
content_hash: sha256:bb66d7de195fa0e0884b1717a4bd3640a51760113f4067b6d864e2b5b72337ec
tokens: 2444
uid: tutorials.docsite.landing-page
reading_time_minutes: 5
---

Getting Started
# Add a Razor landing page at the site root

Route a Razor component at / so a DocSite opens on a hand-built landing page, and swap the doc-page chrome for the sidebar-free FullWidthLayout.

 
By the end of this tutorial the DocSite at `http://localhost:5000/` opens on a Razor landing page — a hero heading, a call to action, and two cards linking into the Guides area — laid out with the sidebar-free `FullWidthLayout` instead of the default doc-page chrome.

 
Along the way the tutorial covers routing a Razor component at `/`, why a `@page "/"` route wins over DocSite's catch-all, and swapping the layout a routed page renders inside.

 
## Prerequisites

 
 - .NET 10 SDK installed
 - Completed [Add doc pages and link between them](https://usepennington.net/tutorials/docsite/first-doc-page.md) — it provides the single-area host and the `install` / `configure` guide pages this landing page links to
 
 
The finished code for this tutorial lives in [examples/DocSitePagesAndLinksExample](https://github.com/usepennington/pennington/tree/main/examples/DocSitePagesAndLinksExample).

 
---

 
## 1. Clear the root so a Razor component can claim it

 
The host from [Add doc pages and link between them](https://usepennington.net/tutorials/docsite/first-doc-page.md) binds one content area, `guides`, to the `/guides/` tab. If you also followed [Scaffold a documentation site with DocSite](https://usepennington.net/tutorials/docsite/scaffold.md), a `Content/index.md` is serving the root — that's the markdown landing page this tutorial replaces with a routed Razor component. Delete it so the root is free, then confirm `/` returns a 404 before you route a component at it.

 
**Delete `Content/index.md`**

 
Remove the scaffold's root markdown page. With nothing bound to the root — no `Content/index.md` and no routed component pointed at `/` — a request to `/` returns a 404.

 
**Run the host and visit the root**

 
```bash
dotnet run
```

 
Open `http://localhost:5000/` in a browser.

 
> [!CHECKPOINT]
>  - `http://localhost:5000/` returns a 404 — nothing serves the root.
>  - `http://localhost:5000/guides/` still renders the Guides hub from [Add doc pages and link between them](https://usepennington.net/tutorials/docsite/first-doc-page.md).

---

 
## 2. Route a Razor component at the root

 
A routed Razor component whose `@page` template is `/` owns the root URL. `AddDocSite` adds your project's assembly to the routing assemblies it hands both the live Blazor router and the static build's page scanner, so a `@page` component in your project is picked up by both with no extra wiring. And a literal `/` route is more specific than DocSite's own catch-all, so it wins the match.

 
**Create `Components/Index.razor`**

 
Create a `Components/` folder at the project root and add `Index.razor` with a `@page "/"` directive and minimal markup.

 
```razor
@page "/"
  
<h1>Pages &amp; Links</h1>
<p>The site root now renders a Razor component.</p>
```

 
The `@page "/"` directive is the whole wiring — no `Program.cs` change, no registration call.

 
**Restart the host**

 
A `.razor` edit is a compile change, so stop the host and run `dotnet run` again to pick up the new component.

 
> [!CHECKPOINT]
>  - `http://localhost:5000/` no longer 404s — it renders the **Pages & Links** heading.
>  - The page is wrapped in the default doc-page chrome: a sidebar on the left and an outline rail on the right. The next unit replaces that layout.

---

 
## 3. Switch to the full-width layout

 
A routed component with no `@layout` directive renders inside DocSite's default, `MainLayout` — the three-column doc-page chrome with the sidebar and outline rail. A landing page wants the header and footer but not the navigation columns. `FullWidthLayout` is exactly that shape.

 
**Add a `@layout` directive to `Index.razor`**

 
Add one line under `@page` naming the layout by its full type name.

 
```razor
@page "/"
@layout Pennington.DocSite.Components.Layout.FullWidthLayout
  
<h1>Pages &amp; Links</h1>
<p>The site root now renders a Razor component.</p>
```

 
`FullWidthLayout` keeps the DocSite header and footer and gives the page the full content width — no sidebar, no outline rail.

 
**Restart the host**

 
The `@layout` directive is another `.razor` edit, so stop the host and run `dotnet run` again to recompile.

 
> [!CHECKPOINT]
>  - `http://localhost:5000/` renders the heading across the full content width.
>  - The sidebar and outline rail are gone; the DocSite header and footer remain.

---

 
## 4. Build out the landing page

 
With routing and layout settled, the component is plain Razor markup. Fill it with a hero, a call to action, and two cards linking into the Guides area. Styling is [MonorailCSS](https://monorailcss.github.io/MonorailCss.Framework/) utility classes using the semantic palette — `primary`, `accent`, `base` — with a `dark:` variant on every color-bearing utility.

 
**Replace `Index.razor` with the finished landing page**

 
```razor:symbol
@page "/"
@layout Pennington.DocSite.Components.Layout.FullWidthLayout
@using Microsoft.AspNetCore.Components.Web
  
@* A Razor component named Index with @page "/" owns the root URL. DocSite
   registers this project's assembly in its routing assemblies, so the literal
   "/" route is picked up by both the live Blazor router and the static build —
   and it beats the catch-all in Pages.razor. @layout swaps the sidebar layout
   for FullWidthLayout, which keeps the header and footer but drops the nav. *@
  
<PageTitle>Pages &amp; Links</PageTitle>
  
<section class="py-12 lg:py-20">
    <p class="text-xs font-display font-semibold tracking-widest uppercase text-primary-600 dark:text-primary-400 mb-4">
        Pennington DocSite
    </p>
    <h1 class="font-display text-4xl lg:text-6xl font-bold tracking-tight text-base-900 dark:text-base-50 leading-tight mb-6 text-balance">
        A docs site with a front door.
    </h1>
    <p class="text-base lg:text-lg text-base-600 dark:text-base-400 max-w-2xl mb-8 leading-relaxed">
        Every guide in one place — installing Pennington, configuring the host,
        and the linking patterns that hold a documentation site together.
    </p>
    <div class="flex flex-wrap items-center gap-3">
        <a href="/guides/"
           class="inline-flex items-center font-display font-semibold bg-primary-600 hover:bg-primary-500 text-white rounded-xl px-6 py-3 transition-colors">
            Read the guides
        </a>
        <a href="https://github.com/usepennington/pennington"
           class="inline-flex items-center font-display font-semibold text-base-700 dark:text-base-200 hover:text-primary-700 dark:hover:text-primary-400 rounded-xl px-5 py-3 ring-1 ring-base-300 dark:ring-base-700 transition-colors">
            View on GitHub
        </a>
    </div>
</section>
  
<section class="pb-16 lg:pb-24">
    <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
        <a href="/guides/install"
           class="rounded-2xl border border-base-200 dark:border-base-800 bg-base-50 dark:bg-base-900/50 p-6 transition-colors hover:border-primary-400 dark:hover:border-primary-500">
            <h2 class="font-display text-xl font-semibold text-base-900 dark:text-base-50 mb-2">
                Install Pennington
            </h2>
            <p class="text-sm text-base-600 dark:text-base-400 leading-relaxed">
                Add the package and stand up the DocSite host.
            </p>
        </a>
        <a href="/guides/configure"
           class="rounded-2xl border border-base-200 dark:border-base-800 bg-base-50 dark:bg-base-900/50 p-6 transition-colors hover:border-primary-400 dark:hover:border-primary-500">
            <h2 class="font-display text-xl font-semibold text-base-900 dark:text-base-50 mb-2">
                Configure the site
            </h2>
            <p class="text-sm text-base-600 dark:text-base-400 leading-relaxed">
                Set the title, footer, and area routing.
            </p>
        </a>
    </div>
</section>
```

 
The two cards link to `/guides/install` and `/guides/configure` — the pages built in [Add doc pages and link between them](https://usepennington.net/tutorials/docsite/first-doc-page.md). `<PageTitle>` sets the browser tab text, the same component DocSite uses on doc pages.

 
**Restart the host and open the root**

 
Stop the host and run `dotnet run` again to recompile the component, then open `http://localhost:5000/`.

 
> [!CHECKPOINT]
>  - `http://localhost:5000/` renders the hero heading, the **Read the guides** button, and two guide cards.
>  - Clicking a card navigates to the matching guide page; the **Read the guides** button lands on `/guides/`.
>  - Run `dotnet run -- build` — the static build's page scanner picks up the same `@page "/"` route and writes the landing page to `output/index.html`.

---

 
## Summary

 
 - A Razor component with `@page "/"` owns the site root — `AddDocSite` already routes your project's assembly, so the directive is the whole wiring.
 - A literal `/` route beats DocSite's catch-all, and the same route is honored by both the live host and the static build.
 - A routed component defaults to `MainLayout`; a `@layout` directive naming `FullWidthLayout` drops the sidebar for a landing-page shape.
 - The component body is ordinary Razor styled with MonorailCSS — semantic palette utilities, `dark:` variants, and links straight into the content areas.
 
 
[Previous
                
                Organize content with sections and areas](https://usepennington.net/tutorials/docsite/sections-and-areas.md)[Next
                    
                Add a blog to your documentation site](https://usepennington.net/tutorials/docsite/add-a-blog.md)