Rewrote all the docs - more noob friendly now.

Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
2026-05-05 23:55:26 +05:00
parent e483bf73e7
commit f6ae86617c
35 changed files with 2159 additions and 2341 deletions
+155 -41
View File
@@ -1,32 +1,141 @@
# Getting Started
This guide gets the solution running locally and explains what happens during startup.
This guide walks you through everything you need to get the project running locally — from installing tools to understanding why certain architectural decisions were made.
---
## What is in this solution
- `Htmx.ApiDemo`: ASP.NET Core app (Minimal API + generated HTMX endpoints)
- `Htmx.SourceGenerator`: Roslyn source generator that discovers `.htmx` files and generates endpoint mapping code
- `Htmx.slnx`: solution file at the repository root
| Project | Purpose |
|---|---|
| `Htmx.ApiDemo` | ASP.NET Core web app using Minimal APIs and server-rendered HTMX templates |
| `Htmx.SourceGenerator` | Roslyn source generator that reads `.htmx` template files and generates endpoint mapping code at build time |
The solution file is `Htmx.slnx` at the repository root.
---
## Prerequisites
- .NET SDK 10.x (target framework is `net10.0`)
- Node.js + npm (used for Tailwind CSS compilation during build)
- MongoDB running locally on `mongodb://localhost:27017`
Install the following before cloning the repo.
### .NET SDK
The project targets `net10.0`. Download the .NET 10 SDK from [dot.net](https://dotnet.microsoft.com/download).
Verify with:
```bash
dotnet --version
```
### Node.js and npm
Tailwind CSS is compiled during the build using the Tailwind CLI via `npx`. Node.js must be installed.
Download from [nodejs.org](https://nodejs.org). Verify with:
```bash
node -v
npm -v
```
### MongoDB
The app stores data in MongoDB. You need a local instance running on `mongodb://localhost:27017`.
**Windows:**
Download and install [MongoDB Community Server](https://www.mongodb.com/try/download/community). During installation, choose to run MongoDB as a Windows Service so it starts automatically.
**Linux:**
Follow the official guide for your distro at [docs.mongodb.com/manual/administration/install-on-linux](https://www.mongodb.com/docs/manual/administration/install-on-linux/). For Ubuntu/Debian:
```bash
sudo systemctl start mongod
sudo systemctl enable mongod # start on boot
```
**MongoDB Compass (optional but recommended):**
Compass is a GUI for browsing and querying your MongoDB data. Download it from [mongodb.com/products/compass](https://www.mongodb.com/products/compass). Connect it to `mongodb://localhost:27017` to inspect collections while developing.
---
## VS Code setup
### Required extensions
- **C# Dev Kit** — provides IntelliSense, debugging, and project support for .NET
Search for `ms-dotnettools.csdevkit` in the Extensions panel.
- **C# (OmniSharp / Roslyn)** — included with C# Dev Kit but can also be installed standalone as `ms-dotnettools.csharp`.
### Recommended settings
Add the following to your workspace or user `settings.json`. This teaches VS Code to treat `.htmx` files as HTML (for syntax highlighting and formatting) and nests generated companion files under their parent in the Explorer sidebar so the file tree stays clean.
```jsonc
{
"files.associations": {
"*.htmx": "html"
},
"explorer.fileNesting.enabled": true,
"explorer.fileNesting.expand": false,
"explorer.fileNesting.patterns": {
"*.razor": "$(capture).razor.cs, $(capture).razor.css, $(capture).razor.js",
"*.htmx": "${capture}.htmx.cs, ${capture}.htmx.routing.cs, ${capture}.g.cs, ${capture}.css"
}
}
```
Without `files.associations`, `.htmx` files open as plain text with no highlighting. Without file nesting, every generated `.htmx.cs` and `.htmx.routing.cs` file appears as a separate top-level entry in the Explorer, making it hard to navigate.
### Optional extension
- **Tailwind CSS Fold** — collapses long Tailwind class strings in the editor so markup is easier to read. Search for `stivo.tailwind-fold`. This is purely a cosmetic convenience and has no effect on the build.
---
## Understanding AOT
AOT (Ahead-of-Time compilation) means the app is compiled to native machine code before it runs, rather than relying on the .NET JIT at runtime. This project has AOT enabled (`<PublishAot>true</PublishAot>` in the `.csproj`).
### Why AOT matters here
AOT produces smaller, faster deployments with no JIT warmup time. For a web app handling many requests, startup time and binary size are real concerns — especially in containerized or serverless environments.
### What AOT prevents you from doing
AOT is a significant constraint. It eliminates entire categories of patterns that are common in standard .NET development:
- **No Entity Framework Core** — EF Core relies heavily on runtime reflection and expression compilation. It is not AOT-compatible. This project uses the MongoDB driver directly instead.
- **No runtime reflection** — `Type.GetProperties()`, `Activator.CreateInstance()`, dynamic proxies, and similar patterns do not work (or produce warnings/errors) under AOT. If a pattern depends on inspecting types at runtime, it will not survive.
- **Many NuGet packages are incompatible** — Any package that uses reflection internally (serializers, mappers, validators, ORMs, DI containers with convention scanning, etc.) may break. Check a package's AOT compatibility before adding it.
- **Source generator-based serialization required** — Rather than `JsonSerializer.Serialize(myObject)` discovering properties at runtime, you must register types with a `JsonSerializerContext` subclass (see `AppJsonSerializerContext.cs`). The serializer then uses generated code instead of reflection.
- **Route handler code generation** — ASP.NET Core's Minimal API generator produces code for request binding and response writing. Some third-party packages produce code that conflicts with this. If adding a package causes build errors in generated files, AOT incompatibility is the likely cause.
The practical rule: before reaching for a package or pattern you know from standard ASP.NET Core, check whether it is AOT-compatible. The project will compile normally in Debug mode even with AOT-incompatible code — AOT issues typically only surface during `dotnet publish`.
---
## First-time setup
From the repository root:
Clone the repo, then install the npm dependencies that the build needs:
```bash
cd Htmx.ApiDemo
npm install
```
Why this is required:
This installs the Tailwind CSS CLI package. The build runs `npx @tailwindcss/cli` as an MSBuild step, so if this is skipped the build will fail with a missing command error.
- The app build runs Tailwind via `npx @tailwindcss/cli ...` in a custom MSBuild target.
- Without `npm install`, build fails because the Tailwind CLI package is missing.
---
## Run the app
@@ -36,57 +145,62 @@ From the repository root:
dotnet run --project Htmx.ApiDemo/Htmx.ApiDemo.csproj
```
Default local URL:
The app listens on `http://localhost:5120` by default (configured in `Htmx.ApiDemo/Properties/launchSettings.json`).
- `http://localhost:5120`
This comes from the launch profile in `Htmx.ApiDemo/Properties/launchSettings.json`.
---
## Verify it works
1. Open `http://localhost:5120`
2. If you are not authenticated, middleware redirects to `/login`
3. Create an account at `/register`
4. Sign in and navigate the app
1. Open `http://localhost:5120` in your browser.
2. If you are not signed in, the middleware redirects you to `/login` — this is expected.
3. Go to `/register` and create an account.
4. Sign in and explore the app.
## What startup config does
---
`Htmx.ApiDemo/Program.cs` configures:
## What happens at startup
- MongoDB DI and index initialization (`EnsureIndexesAsync`)
- Cookie authentication + authorization
`Program.cs` wires up the following in order:
- MongoDB service registration and index initialization (`EnsureIndexesAsync`)
- Cookie-based authentication and authorization
- Antiforgery middleware
- AOT-friendly JSON resolver chain using `AppJsonSerializerContext`
- Endpoint registration via generated mapping call:
- `app.MapHtmxApiDemoEndpoints();`
- AOT-compatible JSON serialization via `AppJsonSerializerContext`
- All generated HTMX endpoints via `app.MapHtmxApiDemoEndpoints()`
## Build behavior worth knowing
---
- Tailwind CSS is compiled before build into `Htmx.ApiDemo/wwwroot/css/output.css`
- `.htmx` files are treated as generator inputs (`<AdditionalFiles Include="**/*.htmx" />`)
- AOT is enabled (`<PublishAot>true</PublishAot>`), so reflection-heavy patterns can break publish/runtime
## Build details
## Optional: publish as AOT
- **Tailwind** is compiled into `wwwroot/css/output.css` as a pre-build step.
- **`.htmx` files** are passed to the source generator as `<AdditionalFiles>`. The generator reads them and produces the abstract base classes and routing code.
- **AOT** is active on publish. Run a publish build early and often to catch incompatibilities before they accumulate.
### Publish (AOT)
```bash
dotnet publish Htmx.ApiDemo/Htmx.ApiDemo.csproj -c Release
```
Use this early to catch AOT issues while developing features.
---
## Troubleshooting
### Build fails on Tailwind command
### Build fails Tailwind command not found
- Run `npm install` inside `Htmx.ApiDemo`
- Confirm `node -v` and `npm -v` are available
Run `npm install` inside the `Htmx.ApiDemo` directory. Confirm `node` and `npm` are on your `PATH`.
### Mongo connection errors
### MongoDB connection errors at startup
- Confirm MongoDB is running on `localhost:27017`
- Confirm `ConnectionStrings:DefaultConnection` in `Htmx.ApiDemo/appsettings.json`
- Confirm the MongoDB service is running (`mongod`).
- Check that `ConnectionStrings:DefaultConnection` in `appsettings.json` points to `mongodb://localhost:27017`.
### App keeps redirecting to login
### App always redirects to `/login`
- This is expected for unauthenticated routes
- Register at `/register` or sign in at `/login`
This is intentional. Unauthenticated requests are redirected by the auth middleware. Register at `/register` first.
### AOT warnings or errors on publish
- Look at the warning message — it usually names the type or method causing the issue.
- Remove or replace the offending package or pattern with an AOT-compatible alternative.
- Run `dotnet publish` regularly during development so issues do not pile up.