Skip to content

Frontend Django Svelte

paulhectork edited this page Feb 12, 2026 · 2 revisions

Communication between Django templates and Svelte components

In AIKON, we use Svelte components inside Django templates, which requires:

  1. to pass variables from the Django backend, to Django templates, to Svelte
  2. to import and use Svelte components from Django templates

We take the example of the Witness/Regions view.

1. Pass variables from Django to Django templates

The Django View defines

  1. template_name: an HTML template
  2. get_context_data: a funciton defining context, a dictionnary of context variables that will be accessible in the HTML template.
# webapp/views/admin.py
class WitnessRegionsView(AbstractRecordView):
    model = Witness
    template_name = "webapp/witness.html"   # <-- HTML template to use
    pk_url_kwarg = "id"
    fields = []

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)   # <-- context variables available in the template
        context["is_validated"] = True
        context["img_nb"] = None

        witness = self.get_record()
        context["view_title"] = f"{witness}"
        context["witness"] = witness.get_json(
            request_user=self.request.user,
            full_metadata=True,
        )

2. Pass context data from Django templates to Svelte views

The HTML template can access variables using {{ context_variable_name }}. We do 2 things:

  1. in a JS block, pass context data to Javascript by assigning it to constants.
  2. import the Svelte view as a JS module
<!-- witness.html -->
{% block extra_js %}
<!-- 1. assign context variables to JS consts -->
<script>
    const witness = {{ witness|js|safe }};
    const manifest = "{{ manifest }}";
    const manifests = {{ manifests|js|safe }};
    const imgPrefix = "{{ img_prefix }}";
    const isValidated = {% if is_validated %}true{% else %}false{% endif %};
    const nbOfPages = {% if img_nb %}{{img_nb}}{% else %}0{% endif %};
    const trailingZeros = {% if img_zeros %}{{img_zeros}}{% else %}0{% endif %};
    const viewTitle = "{{ view_title }}";
    const editUrl = "{{ witness.edit_url }}";
</script>

<!-- 2. import the Svelte view -->
<script type="module" src="{% static 'svelte/witnessView/witness.js' %}"></script>
{% endblock %}

3. Define a JS entrypoint for your svelte view.

In the HTML template, we import a witness.js. In witness.js, instanciate your view and export it.

The WitnessView.svelte itself is a normal Svelte view.

// witness.js
import WitnessView from "./WitnessView.svelte";

const WitnessApp = new WitnessView({
    target: document.getElementById("witness-view"),
    props: {
        viewTitle, 
        editUrl,  
        witness, 
        manifest,  
        manifests, 
        isValidated,
        imgPrefix,  
        nbOfPages, 
        trailingZeros 
    }
});

export default WitnessApp;

This is where the magic happens: the value of the props with which WitnessView is instanciated are all inherited from the parent witness.html, which itself inherited those values from the Django context !

Clone this wiki locally