# Hooks

Doctopus can run commands before and after a build.

Hooks are configured in `doctopus.yaml` as argv arrays:

```yaml
hooks:
  pre_build: ["uv", "run", "--script", "hooks/pre_build.py"]
  post_build: ["uv", "run", "--script", "hooks/post_build.py"]
```

Each array is executed directly. The first item is the executable. All following items are passed as arguments.

Hooks run from the directory that contains `doctopus.yaml`. That makes relative paths like `hooks/pre_build.py` resolve from your project root.

## When Hooks Run

- `pre_build` runs before Doctopus starts generating output.
- `post_build` runs after the site has been written successfully.

If a hook exits with a non-zero status, the build fails.

## Recommendation: Use `uv`

For Python hooks, prefer [`uv`](https://docs.astral.sh/uv/). It keeps hook scripts easy to run and solves dependency management without requiring a separate virtual environment setup.

One nice pattern is a self-contained script with dependency metadata in comments:

```python
# /// script
# dependencies = [
#   "pillow>=11",
# ]
# ///

from pathlib import Path

Path("docs/generated.md").write_text("# Generated\n", encoding="utf-8")
```

Then run it with:

```yaml
hooks:
  pre_build: ["uv", "run", "--script", "hooks/pre_build.py"]
```

This keeps hook dependencies close to the script that needs them.
