Hooks¶
Hooks post-process the payload after it is built. Use them to add a field to every page, rewrite a description per section, or inject site-wide metadata.
Hooks are config-scoped. They live on the SEOConfig that carries them,
so build_seo_payload stays a pure function of its inputs and two configs in
the same process cannot interfere.
Registering a hook¶
The hook signature¶
A hook receives three arguments and must return the payload:
payloadis a plain dict in the canonical snake_case format, including the changes made by previous hooks.entityis the originalSEOEntity.configis theSEOConfigthat carried the hook.
Hook points¶
| Name | When it runs |
|---|---|
post_process |
At the end of the build, before returning |
post_process is the only built-in hook point.
Order and scoping¶
Hooks run in registration order; the last writer of a field wins. Because the registry is part of the config, hooks are scoped: a config without hooks is unaffected.
hooks_a = HookRegistry()
hooks_a.register("post_process", lambda p, e, c: {**p, "site": "A"})
hooks_b = HookRegistry()
hooks_b.register("post_process", lambda p, e, c: {**p, "site": "B"})
a = build_seo_payload(entity, "/x", config_a) # config_a has hooks_a
b = build_seo_payload(entity, "/x", config_b) # config_b has hooks_b
assert a["site"] == "A"
assert b["site"] == "B"
Managing hooks¶
| Python | JavaScript | Purpose |
|---|---|---|
register |
register |
Add a hook |
hook |
hook |
Decorator form |
unregister |
unregister |
Remove a hook |
run |
run |
Run all hooks for a name |
clear |
clear |
Remove all hooks, or those under a name |
get_registered |
size |
Inspect the registry |
Determinism and purity¶
Keep hooks pure: no clock reads, no random values, no network calls. A hook that reads the environment breaks the determinism guarantee for the config that carries it.
If a hook raises, the exception propagates and the remaining hooks are skipped. Errors should be loud; a failing hook is a bug.
Recap¶
- Hooks post-process the payload and return it.
- They are config-scoped, ordered, and deterministic when kept pure.
- Use
SEOOverridesfor per-page changes and hooks for site-wide ones.