> ## Documentation Index
> Fetch the complete documentation index at: https://easyaf.nimbleapps.cloud/llms.txt
> Use this file to discover all available pages before exploring further.

# IndexedDB

> NoSQL key-value storage for Blazor WebAssembly applications

IndexedDB provides a powerful NoSQL database API built into every modern browser.
BlazorEssentials.IndexedDb makes it easy to use from your Blazor WebAssembly applications
with a strongly-typed C# API.

> [card] No Setup Required
>
> Uses the browser's built-in IndexedDB - no server or external dependencies.

> [card] Offline Ready
>
> Data persists locally, enabling full offline functionality.

> [card] Type-Safe
>
> Object stores are strongly typed with compile-time safety.

> [card] Indexed Queries
>
> Create indexes for fast lookups on any property.

## Installation

```bash theme={"dark"}
dotnet add package BlazorEssentials.IndexedDb
```

## Quick Start

### Define Your Entities

Use attributes to configure how entities are stored:

```csharp Models/TodoItem.cs theme={"dark"}
using CloudNimble.BlazorEssentials.IndexedDb;

[ObjectStore("todos")]
public class TodoItem
{
    public int Id { get; set; }

    public string Title { get; set; } = "";

    public bool IsCompleted { get; set; }

    [Index]
    public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
}
```

### Create Your Database

Inherit from `IndexedDbDatabase` and add `IndexedDbObjectStore<T>` properties:

```csharp Data/AppDatabase.cs theme={"dark"}
using CloudNimble.BlazorEssentials.IndexedDb;
using Microsoft.JSInterop;

public class AppDatabase : IndexedDbDatabase
{
    public IndexedDbObjectStore<TodoItem> Todos { get; set; }

    public AppDatabase(IJSRuntime jsRuntime) : base(jsRuntime)
    {
        Name = "MyAppDb";
        Version = 1;
    }
}
```

### Register and Use

```csharp Program.cs theme={"dark"}
builder.Services.AddScoped<AppDatabase>();
```

```razor MyComponent.razor theme={"dark"}
@inject AppDatabase Database

@code {
    private List<TodoItem> todos = new();

    protected override async Task OnInitializedAsync()
    {
        await Database.OpenAsync();
        todos = await Database.Todos.GetAllAsync();
    }
}
```

## CRUD Operations

### Create

```csharp theme={"dark"}
var todo = new TodoItem
{
    Id = 1,
    Title = "Learn Blazor",
    IsCompleted = false
};

await Database.Todos.AddAsync(todo);
```

### Read

```csharp Get All theme={"dark"}
var allTodos = await Database.Todos.GetAllAsync();
```

```csharp Get by Key theme={"dark"}
var todo = await Database.Todos.GetAsync(1);
```

```csharp Get by Index theme={"dark"}
var recentTodos = await Database.Todos
    .GetByIndexAsync("CreatedAt", KeyRange.LowerBound(DateTime.Today));
```

### Update

```csharp theme={"dark"}
var todo = await Database.Todos.GetAsync(1);
todo.IsCompleted = true;

await Database.Todos.PutAsync(todo);
```

### Delete

```csharp Delete by Key theme={"dark"}
await Database.Todos.DeleteAsync(1);
```

```csharp Clear All theme={"dark"}
await Database.Todos.ClearAsync();
```

## Indexes

Create indexes for fast lookups on frequently queried properties:

```csharp theme={"dark"}
[ObjectStore("users")]
public class User
{
    public int Id { get; set; }

    [Index]
    public string Email { get; set; } = "";

    [Index(Unique = false)]
    public string Department { get; set; } = "";
}
```

Query using indexes:

```csharp theme={"dark"}
// Find user by email
var user = await Database.Users
    .GetByIndexAsync("Email", "john@example.com")
    .FirstOrDefaultAsync();

// Find all users in a department
var engineers = await Database.Users
    .GetByIndexAsync("Department", "Engineering");
```

## Key Ranges

Use `KeyRange` for range queries on indexed properties:

```csharp theme={"dark"}
// Items created today
var todayItems = await Database.Todos
    .GetByIndexAsync("CreatedAt", KeyRange.LowerBound(DateTime.Today));

// Items in a date range
var rangeItems = await Database.Todos
    .GetByIndexAsync("CreatedAt", KeyRange.Bound(startDate, endDate));
```

## Best Practices

> [accordion] Use meaningful key paths
>
> Choose key paths that uniquely identify your entities. Auto-incrementing integers
> or GUIDs work well for most cases.

> [accordion] Create indexes strategically
>
> Only create indexes on properties you'll query frequently. Each index adds
> storage overhead and slows down writes.

> [accordion] Handle version upgrades
>
> When changing your schema, increment the `Version` property. IndexedDB will
> trigger an upgrade event to migrate existing data.

## API Reference

> [card] [IndexedDbDatabase](https://easyaf.nimbleapps.cloud/blazoressentials/api-reference/CloudNimble/BlazorEssentials/IndexedDb/IndexedDbDatabase.md)
>
> Base class for IndexedDB databases

> [card] [IndexedDbObjectStore](https://easyaf.nimbleapps.cloud/blazoressentials/api-reference/CloudNimble/BlazorEssentials/IndexedDb/IndexedDbObjectStore.md)
>
> Typed object store for CRUD operations

> [card] [KeyRange](https://easyaf.nimbleapps.cloud/blazoressentials/api-reference/CloudNimble/BlazorEssentials/IndexedDb/KeyRange.md)
>
> Range queries for indexed lookups

> [card] [IndexAttribute](https://easyaf.nimbleapps.cloud/blazoressentials/api-reference/CloudNimble/BlazorEssentials/IndexedDb/IndexAttribute.md)
>
> Define indexes on properties


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.