Extension hooks¤
Overview of all the extension hooks available in Django Components.
Read more on Extensions.
Hooks¤
on_component_class_created ¤
on_component_class_created(ctx: OnComponentClassCreatedContext) -> None
Available data:
| name | type | description |
|---|---|---|
component_cls | type['Component'] | The created Component class |
on_component_class_deleted ¤
on_component_class_deleted(ctx: OnComponentClassDeletedContext) -> None
Called when a Component class is being deleted.
This hook is called before the Component class is deleted from memory.
Use this hook to perform any cleanup related to the Component class.
Example:
from django_components import ComponentExtension, OnComponentClassDeletedContext
class MyExtension(ComponentExtension):
def on_component_class_deleted(self, ctx: OnComponentClassDeletedContext) -> None:
# Remove Component class from the extension's cache on deletion
self.cache.pop(ctx.component_cls, None)
Available data:
| name | type | description |
|---|---|---|
component_cls | type['Component'] | The to-be-deleted Component class |
on_component_data ¤
on_component_data(ctx: OnComponentDataContext) -> None
Called when a Component was triggered to render, after a component's context and data methods have been processed.
This hook is called after Component.get_template_data(), Component.get_js_data() and Component.get_css_data().
This hook runs after on_component_input.
Use this hook to modify or validate the component's data before rendering.
Example:
Available data:
| name | type | description |
|---|---|---|
component | Component | The Component instance that is being rendered |
component_cls | type['Component'] | The Component class |
component_id | str | The unique identifier for this component instance |
context_data | dict | Deprecated. Use template_data instead. Will be removed in v1.0. |
css_data | dict | Dictionary of CSS data from Component.get_css_data() |
js_data | dict | Dictionary of JavaScript data from Component.get_js_data() |
template_data | dict | Dictionary of template data from Component.get_template_data() |
on_component_input ¤
on_component_input(ctx: OnComponentInputContext) -> str | None
Called when a Component was triggered to render, but before a component's context and data methods are invoked.
Use this hook to modify or validate component inputs before they're processed.
This is the first hook that is called when rendering a component. As such this hook is called before Component.get_template_data(), Component.get_js_data(), and Component.get_css_data() methods, and the on_component_data hook.
This hook also allows to skip the rendering of a component altogether. If the hook returns a non-null value, this value will be used instead of rendering the component.
You can use this to implement a caching mechanism for components, or define components that will be rendered conditionally.
Warning
When any extension short-circuits a component (by returning a non-null value), the rest of that component's render is skipped, including on_component_data and on_component_rendered.
Extensions run in order, and the built-in extensions (including the cache) run before user extensions. So your on_component_input may run even when a later extension short-circuits the same component.
In practice this means: if you save something at the start of a render (here, in on_component_input) so you can use or remove it later in on_component_rendered, that later hook might never run. And if you saved it in a dictionary that lives on your extension, nothing ever removes that entry, so the dictionary grows by one with every skipped render. That is a memory leak.
To avoid this, store anything you need for a single render on the component itself, or on something that lives only as long as the component (such as its config object for your extension, or Slot.extra). It is then discarded automatically once the component is done, whether or not on_component_rendered runs.
Example:
from django_components import ComponentExtension, OnComponentInputContext
class MyExtension(ComponentExtension):
def on_component_input(self, ctx: OnComponentInputContext) -> None:
# Add extra kwarg to all components when they are rendered
ctx.kwargs["my_input"] = "my_value"
Warning
In this hook, the components' inputs are still mutable.
As such, if a component defines Args, Kwargs, Slots types, these types are NOT yet instantiated.
Instead, component fields like Component.args, Component.kwargs, Component.slots are plain list / dict objects.
Available data:
| name | type | description |
|---|---|---|
args | list | List of positional arguments passed to the component |
component | Component | The Component instance that received the input and is being rendered |
component_cls | type['Component'] | The Component class |
component_id | str | The unique identifier for this component instance |
context | Context | The Django template Context object |
kwargs | dict | Dictionary of keyword arguments passed to the component |
slots | dict[str, 'Slot'] | Dictionary of slot definitions |
on_component_registered ¤
on_component_registered(ctx: OnComponentRegisteredContext) -> None
Called when a Component class is registered with a ComponentRegistry.
This hook is called after a Component class is successfully registered.
Example:
Available data:
| name | type | description |
|---|---|---|
component_cls | type['Component'] | The registered Component class |
name | str | The name the component was registered under |
registry | ComponentRegistry | The registry the component was registered to |
on_component_rendered ¤
on_component_rendered(ctx: OnComponentRenderedContext) -> str | None
Called when a Component was rendered, including all its child components.
Use this hook to access or post-process the component's rendered output.
This hook works similarly to Component.on_render_after():
-
To modify the output, return a new string from this hook. The original output or error will be ignored.
-
To cause this component to return a new error, raise that error. The original output and error will be ignored.
-
If you neither raise nor return string, the original output or error will be used.
Examples:
Change the final output of a component:
from django_components import ComponentExtension, OnComponentRenderedContext
class MyExtension(ComponentExtension):
def on_component_rendered(self, ctx: OnComponentRenderedContext) -> str | None:
# Append a comment to the component's rendered output
return ctx.result + "<!-- MyExtension comment -->"
Cause the component to raise a new exception:
from django_components import ComponentExtension, OnComponentRenderedContext
class MyExtension(ComponentExtension):
def on_component_rendered(self, ctx: OnComponentRenderedContext) -> str | None:
# Raise a new exception
raise Exception("Error message")
Return nothing (or None) to handle the result as usual:
from django_components import ComponentExtension, OnComponentRenderedContext
class MyExtension(ComponentExtension):
def on_component_rendered(self, ctx: OnComponentRenderedContext) -> str | None:
if ctx.error is not None:
# The component raised an exception
print(f"Error: {ctx.error}")
else:
# The component rendered successfully
print(f"Result: {ctx.result}")
Available data:
| name | type | description |
|---|---|---|
component | Component | The Component instance that is being rendered |
component_cls | type['Component'] | The Component class |
component_id | str | The unique identifier for this component instance |
error | Exception | None | The error that occurred during rendering, or None if rendering was successful |
result | str | None | The rendered component, or None if rendering failed |
on_component_unregistered ¤
on_component_unregistered(ctx: OnComponentUnregisteredContext) -> None
Called when a Component class is unregistered from a ComponentRegistry.
This hook is called after a Component class is removed from the registry.
Example:
Available data:
| name | type | description |
|---|---|---|
component_cls | type['Component'] | The unregistered Component class |
name | str | The name the component was registered under |
registry | ComponentRegistry | The registry the component was unregistered from |
on_css_loaded ¤
on_css_loaded(ctx: OnCssLoadedContext) -> str | None
Called when a Component's CSS is loaded as a string.
This hook runs only once per Component class and works for both Component.css and Component.css_file.
Use this hook to read or modify the CSS.
To modify the CSS, return a new string from this hook.
Example:
Available data:
| name | type | description |
|---|---|---|
component_cls | type['Component'] | The Component class whose CSS was loaded |
content | str | The CSS content (string) |
on_dependencies ¤
Called when a rendered HTML is being finalized, after all dependencies (JS and CSS) were collected, and before they are rendered as <script> and <link> tags.
Use this hook to access or modify the JS/CSS dependencies, for example to:
- Modify or add dependencies
- Render
<script>tags JS modules withtype="module" - Add CSP nonce to the dependencies
To modify the dependencies, return a tuple of (scripts, styles).
Where:
Example:
from django_components import (
ComponentExtension,
OnDependenciesContext,
Script,
Style,
)
class MyExtension(ComponentExtension):
def on_dependencies(self, ctx: OnDependenciesContext) -> tuple[list["Script"], list["Style"]]:
scripts = ctx.scripts
styles = ctx.styles
# Modify existing scripts and styles
for script in scripts:
if script.kind == "extra":
script.wrap = False
for style in styles:
if style.kind == "extra":
style.attrs["media"] = "print"
# Add extra JS and CSS dependencies (inline content)
scripts.append(
Script(
content="console.log('extension-injected script');",
wrap=False,
)
)
styles.append(
Style(
content="body { background-color: red; }",
)
)
# Add extra JS and CSS dependencies (external URL)
scripts.append(
Script(
url="/static/analytics.js",
content=None,
)
)
styles.append(
Style(
url="/static/print.css",
content=None,
attrs={"media": "print"},
)
)
return (scripts, styles)
Available data:
| name | type | description |
|---|---|---|
scripts | list['Script'] | List of JS scripts to load |
styles | list['Style'] | List of CSS styles to load |
on_extension_created ¤
on_extension_created(ctx: OnExtensionCreatedContext) -> None
Called when a new ComponentExtension instance is created.
Use this hook to perform any initialization or validation of the extension instance.
Example:
Available data:
| name | type | description |
|---|---|---|
extension | ComponentExtension | The created extension |
on_js_loaded ¤
on_js_loaded(ctx: OnJsLoadedContext) -> str | None
Called when a Component's JS is loaded as a string.
This hook runs only once per Component class and works for both Component.js and Component.js_file.
Use this hook to read or modify the JS.
To modify the JS, return a new string from this hook.
Example:
Available data:
| name | type | description |
|---|---|---|
component_cls | type['Component'] | The Component class whose JS was loaded |
content | str | The JS content (string) |
on_registry_created ¤
on_registry_created(ctx: OnRegistryCreatedContext) -> None
Called when a new ComponentRegistry is created.
This hook is called after a new ComponentRegistry instance is initialized.
Use this hook to perform any initialization needed for the registry.
Example:
Available data:
| name | type | description |
|---|---|---|
registry | ComponentRegistry | The created ComponentRegistry instance |
on_registry_deleted ¤
on_registry_deleted(ctx: OnRegistryDeletedContext) -> None
Called when a ComponentRegistry is being deleted.
This hook is called before a ComponentRegistry instance is deleted.
Use this hook to perform any cleanup related to the registry.
Example:
Available data:
| name | type | description |
|---|---|---|
registry | ComponentRegistry | The to-be-deleted ComponentRegistry instance |
on_slot_rendered ¤
on_slot_rendered(ctx: OnSlotRenderedContext) -> str | None
Called when a {% slot %} tag was rendered.
Use this hook to access or post-process the slot's rendered output.
To modify the output, return a new string from this hook.
Example:
from django_components import ComponentExtension, OnSlotRenderedContext
class MyExtension(ComponentExtension):
def on_slot_rendered(self, ctx: OnSlotRenderedContext) -> str | None:
# Append a comment to the slot's rendered output
return ctx.result + "<!-- MyExtension comment -->"
Access slot metadata:
You can access the {% slot %} tag node (SlotNode) and its metadata using ctx.slot_node.
For example, to find the Component class to which belongs the template where the {% slot %} tag is defined, you can use ctx.slot_node.template_component:
from django_components import ComponentExtension, OnSlotRenderedContext
class MyExtension(ComponentExtension):
def on_slot_rendered(self, ctx: OnSlotRenderedContext) -> str | None:
# Access slot metadata
slot_node = ctx.slot_node
slot_owner = slot_node.template_component
print(f"Slot owner: {slot_owner}")
Available data:
| name | type | description |
|---|---|---|
component | Component | The Component instance that contains the {% slot %} tag |
component_cls | type['Component'] | The Component class that contains the {% slot %} tag |
component_id | str | The unique identifier for this component instance |
result | SlotResult | The rendered result of the slot |
slot | Slot | The Slot instance that was rendered |
slot_is_default | bool | Whether the slot is default |
slot_is_required | bool | Whether the slot is required |
slot_name | str | The name of the {% slot %} tag |
slot_node | SlotNode | The node instance of the {% slot %} tag |
on_template_compiled ¤
on_template_compiled(ctx: OnTemplateCompiledContext) -> None
Called when a Component's template is compiled into a Template object.
This hook runs only once per Component class and works for both Component.template and Component.template_file.
Use this hook to read or modify the template (in-place) after it's compiled.
Example:
Available data:
| name | type | description |
|---|---|---|
component_cls | type['Component'] | The Component class whose template was loaded |
template | django.template.base.Template | The compiled template object |
on_template_loaded ¤
on_template_loaded(ctx: OnTemplateLoadedContext) -> str | None
Called when a Component's template is loaded as a string.
This hook runs only once per Component class and works for both Component.template and Component.template_file.
Use this hook to read or modify the template before it's compiled.
To modify the template, return a new string from this hook.
Example:
Available data:
| name | type | description |
|---|---|---|
component_cls | type['Component'] | The Component class whose template was loaded |
content | str | The template string |
name | str | None | The name of the template |
origin | django.template.base.Origin | None | The origin of the template |
Objects¤
OnComponentClassCreatedContext ¤
Attributes:
-
component_cls(type[Component]) –
component_cls instance-attribute ¤
The created Component class
OnComponentClassDeletedContext ¤
Attributes:
-
component_cls(type[Component]) –
component_cls instance-attribute ¤
The to-be-deleted Component class
OnComponentDataContext ¤
Attributes:
-
component(Component) – -
component_cls(type[Component]) – -
component_id(str) – -
context_data(dict) – -
css_data(dict) – -
js_data(dict) – -
template_data(dict) –
component_cls instance-attribute ¤
The Component class
component_id instance-attribute ¤
component_id: str
The unique identifier for this component instance
context_data instance-attribute ¤
context_data: dict
Deprecated. Use template_data instead. Will be removed in v1.0.
js_data instance-attribute ¤
js_data: dict
Dictionary of JavaScript data from Component.get_js_data()
OnComponentInputContext ¤
Attributes:
-
args(list) – -
component(Component) – -
component_cls(type[Component]) – -
component_id(str) – -
context(Context) – -
kwargs(dict) – -
slots(dict[str, Slot]) –
component instance-attribute ¤
component: Component
The Component instance that received the input and is being rendered
component_cls instance-attribute ¤
The Component class
component_id instance-attribute ¤
component_id: str
The unique identifier for this component instance
OnComponentRegisteredContext ¤
Attributes:
-
component_cls(type[Component]) – -
name(str) – -
registry(ComponentRegistry) –
component_cls instance-attribute ¤
The registered Component class
registry instance-attribute ¤
registry: ComponentRegistry
The registry the component was registered to
OnComponentRenderedContext ¤
Attributes:
-
component(Component) – -
component_cls(type[Component]) – -
component_id(str) – -
error(Exception | None) – -
result(str | None) –
component_cls instance-attribute ¤
The Component class
component_id instance-attribute ¤
component_id: str
The unique identifier for this component instance
error instance-attribute ¤
error: Exception | None
The error that occurred during rendering, or None if rendering was successful
OnComponentUnregisteredContext ¤
Attributes:
-
component_cls(type[Component]) – -
name(str) – -
registry(ComponentRegistry) –
component_cls instance-attribute ¤
The unregistered Component class
registry instance-attribute ¤
registry: ComponentRegistry
The registry the component was unregistered from
OnCssLoadedContext ¤
OnDependenciesContext ¤
OnExtensionCreatedContext ¤
OnJsLoadedContext ¤
OnRegistryCreatedContext ¤
Attributes:
-
registry(ComponentRegistry) –
OnRegistryDeletedContext ¤
Attributes:
-
registry(ComponentRegistry) –
registry instance-attribute ¤
registry: ComponentRegistry
The to-be-deleted ComponentRegistry instance
OnSlotRenderedContext ¤
Attributes:
-
component(Component) – -
component_cls(type[Component]) – -
component_id(str) – -
result(SlotResult) – -
slot(Slot) – -
slot_is_default(bool) – -
slot_is_required(bool) – -
slot_name(str) – -
slot_node(SlotNode) –
component instance-attribute ¤
component: Component
The Component instance that contains the {% slot %} tag
component_cls instance-attribute ¤
The Component class that contains the {% slot %} tag
component_id instance-attribute ¤
component_id: str
The unique identifier for this component instance