Static signals#
The static pipeline emits asset_registered, collector_finalized, html_injected, and backend_loaded from next.static.signals.
Import either from next.static.signals or from the aggregator next.signals.
Import receiver modules from AppConfig.ready so receivers exist before the first request.
Signals and payloads#
asset_registered#
Fires after a file is registered with a backend and added to the collector.
The sender is the asset instance.
The payload carries collector and backend.
Note
asset_registered fires once per discovered file inside the render hot path.
Keep receivers cheap and synchronous, and avoid I/O or database queries in them.
from collections import Counter
from django.dispatch import receiver
from next.static.signals import asset_registered
asset_counts: Counter = Counter()
@receiver(asset_registered)
def track_asset(sender, **kwargs) -> None:
asset_counts[sender.kind] += 1
collector_finalized#
Fires when the static manager begins injection, after template rendering has completed and the collector is sealed.
The sender is the collector.
The payload carries page_path, the file path of the rendered page, and request, the active HttpRequest or None for renders outside a request lifecycle.
A standalone zone render never fires this signal because its assets travel in the patch envelope instead of through injection.
from django.dispatch import receiver
from next.static.signals import collector_finalized
@receiver(collector_finalized)
def count_assets(sender, **kwargs) -> None:
styles = sender.assets_in_slot("styles")
scripts = sender.assets_in_slot("scripts")
print(f"{len(styles)} styles, {len(scripts)} scripts")
html_injected#
Fires after placeholder replacement completes. The sender is the static manager.
html_beforeThe raw HTML string the manager received before injection.
html_afterThe HTML string after every slot token was replaced.
collectorThe sealed
StaticCollectorused for this render.placeholders_replacedA tuple of slot names whose token appeared in
html_before. The wholehtml_injecteddispatch is skipped when no receiver is connected, so the tuple is built only on the request paths where a listener is present.injected_bytesA signed
intequal tolen(html_after) - len(html_before). Negative when injection shortens the document, for example when a slot token is longer than the rendered tags it replaces. The preload hint is added before the diff is measured, so underAUTOan empty collector can still produce a positive value because the preload link grows the document.requestThe active
HttpRequestorNone.
backend_loaded#
Fires after the static manager instantiates a configured backend.
The sender is the backend class.
The payload carries config and instance.
Note
backend_loaded re-fires whenever the static manager rebuilds its backend chain.
Tests that toggle STATIC_BACKENDS through override_settings or call reset_default_manager trigger the signal again on the next access.
Make receivers idempotent.
Pipeline placement#
See Static pipeline for where each signal fires relative to discovery and HTML injection.
See also#
See also
Static backends for static backend customisation. Deduplication for the dedup strategy. Signals for the full catalog. Signals reference for the public API.