## Overview

This guide walks you through adding `dioxus-docs-kit` to an existing Dioxus 0.7 project. By the end, you'll have a fully functional documentation site with sidebar navigation, search, and optional OpenAPI reference pages.

## Prerequisites

- A working Dioxus 0.7 project with `features = ["router", "fullstack"]`
- The Dioxus CLI (`dx`): `curl -sSL http://dioxus.dev/install.sh | sh`

## Setup

1. **Add dependencies**
Add `dioxus-docs-kit` and the build helper to your `Cargo.toml`:

```toml
[dependencies]
    dioxus-docs-kit = { version = "0.5", default-features = false }

    [build-dependencies]
    dioxus-docs-kit-build = "0.5"

    [features]
    default = ["web"]
    web = ["dioxus/web", "dioxus-docs-kit/web"]
```

2. **Create the docs directory**
Create your content structure:

```text
docs/
    ├── _nav.json
    ├── getting-started/
    │   └── introduction.mdx
    └── api-reference/
        └── overview.mdx
```

Each `.mdx` file needs frontmatter:

```mdx
---
    title: Introduction
    description: Welcome to the docs
    sidebarTitle: Introduction
    icon: book-open
    ---

    Your content here.
```

3. **Configure navigation**
Create `docs/_nav.json`:

```json
{
      "tabs": ["Docs", "API Reference"],
      "groups": [
        {
          "group": "Getting Started",
          "tab": "Docs",
          "pages": ["getting-started/introduction"]
        },
        {
          "group": "API Reference",
          "tab": "API Reference",
          "pages": ["api-reference/overview"]
        }
      ]
    }
```

4. **Create build.rs**
Add a `build.rs` at the project root to embed content at compile time:

```rust
fn main() {
        dioxus_docs_kit_build::generate_content_map("docs/_nav.json");
    }
```

This reads `_nav.json`, emits `cargo:rerun-if-changed` for all MDX files, and generates a content map in `OUT_DIR`.

5. **Wire up the registry**
In `main.rs`, use the `doc_content_map!()` macro and create the `DocsRegistry`:

```rust
use dioxus::prelude::*;
    use dioxus_docs_kit::{
        DocsConfig, DocsContext, DocsLayout, DocsPageContent,
        DocsRegistry, use_docs_providers,
    };
    use std::sync::LazyLock;

    // Generates doc_content_map() from the build script output
    dioxus_docs_kit::doc_content_map!();

    static DOCS: LazyLock<DocsRegistry> = LazyLock::new(|| {
        DocsConfig::new(
            include_str!("../docs/_nav.json"),
            doc_content_map(),
        )
        .with_default_path("getting-started/introduction")
        .build()
    });
```

To include an OpenAPI spec, chain `.with_openapi()`:

```rust
DocsConfig::new(nav_json, content_map)
        .with_openapi(
            "api-reference",
            include_str!("../docs/api-reference/openapi.yaml"),
        )
        .build()
```

6. **Create the docs layout wrapper**
Create a layout component that provides `DocsContext` and the registry. The `use_docs_providers` hook bundles all the context setup into a single call:

```rust
#[component]
    fn MyDocsLayout() -> Element {
        let nav = use_navigator();
        let route = use_route::<Route>();

        let current_path = use_memo(move || match route.clone() {
            Route::DocsPage { slug } => slug.join("/"),
            _ => String::new(),
        });

        // The constructor defaults the meta fields (`auto_meta: true`,
        // no site_url, no markdown alternate links); use the `with_*`
        // setters to override them.
        let docs_ctx = DocsContext::new(
            current_path,
            "/docs",
            Callback::new(move |path: String| {
                let slug: Vec<String> =
                    path.split('/').map(String::from).collect();
                nav.push(Route::DocsPage { slug });
            }),
        )
        // Public origin used for canonical URLs and OG tags — set it
        // in production.
        .with_site_url("https://your-site.com");

        let providers = use_docs_providers(&*DOCS, docs_ctx);

        rsx! {
            DocsLayout {
                // Use providers.search_open / providers.drawer_open
                // in a custom header if needed
                Outlet::<Route> {}
            }
        }
    }
```

The `DocsProviders` struct returned by the hook gives you access to `search_open` and `drawer_open` signals for wiring up custom header buttons.

7. **Add routes**
Add the docs routes to your `Route` enum:

```rust
#[derive(Debug, Clone, Routable, PartialEq)]
    enum Route {
        #[layout(MyDocsLayout)]
            #[redirect("/docs", || Route::DocsPage {
                slug: vec!["getting-started".into(), "introduction".into()]
            })]
            #[route("/docs/:..slug")]
            DocsPage { slug: Vec<String> },
    }

    #[component]
    fn DocsPage(slug: Vec<String>) -> Element {
        rsx! {
            DocsPageContent { path: slug.join("/") }
        }
    }
```

## What You Get

Once integrated, your docs site includes:

**Sidebar Navigation**
Auto-generated from _nav.json with tab switching and group headings

**Full-Text Search**
Built-in search modal (Cmd+K) across all doc content

**API Reference**
Two-column endpoint pages generated from OpenAPI specs

**Page Navigation**
Previous/next page links at the bottom of every page

## Next Steps

**Customization**
Learn how to theme your site and configure navigation

**Basic Usage**
Explore all available MDX components

