DEV Community

Cover image for Simple Django w/ Svelte
Max
Max

Posted on

Simple Django w/ Svelte

Forewarning

If you are serious about using Django and Svelte you probably just want djangorestframework pkg and django-svelte pkg. This will get you two major things:

  • pass prop data to svelte components
  • POST/PUT/UPDATE/DELETE data via API calls from svelte components. Aka modify and submit data, turning this into a useful two way street as you won't be able to use Django's nice builtin forms.

Final Example: https://gitlab.com/mdpb/svelte-django-example

Goal

I figured rollup turned svelte into a basic .html and .js file, so why not just host those from specific routes in Django?

This way you could rely on the templating in Django, stay in Python land as long as possible, then push a Svelte component or mini-Singe Page Application to the user.

Why?

Some of you may think this setup sounds like old news, or hail from the olden times of Apache servers and the /www directory. But for me the easiest and most familiar path is working 100% on a Single Page App with react/svelte/vue and then pushing it to a CDN via some service like Vercel.

After the frontend code, written in 100% modern javascript, then you make fetch requests to populate the site with data. So you end up making CORS requests. That works fine, little learning curve with CORS if you own the resource you're fetching from.

But it lacks a certain simplicity. I wanted to live on one single domain and manage everything from a single language + framework as much as possible.

Getting into it

  1. Build your svelte component(s) locally.
  2. Compile your svelte page(s) and send them to the static directory for your Django app.
  3. Return a Template from your Route's View like normal, except the .html file you return is gonna have a few extra <script> and <link> tags:
<head>
    <script 
        type="module" 
        src="{% static 'notes/bundle.js' %}">
    </script>
    <link 
        rel='stylesheet' 
        href="{% static 'notes/bundle.css' %}">
    <link 
        rel='stylesheet' 
        href="{% static 'css/global.css' %}">
</head>

Enter fullscreen mode Exit fullscreen mode

This won't leave you with much, you'll be able to send a svelte file off to the user but

  • you won't be able to push Django data into it
  • you won't be able to submit data as simply as standard Django form

But hey! You're pushing svelte out client side!

Details

Start with your URL route:

#your_app/urls.py
...
urlpatterns = [
    path('new/svelte/', views.svelte, name='new'),
]
...
Enter fullscreen mode Exit fullscreen mode

You'll need a View for that:

#your_app/views.py
def svelte(request):
    template = loader.get_template('notes/new-svelte.html')
    return HttpResponse(template.render(context=None, request=request))
Enter fullscreen mode Exit fullscreen mode

And of course a Template:

<!-- your_app/template/your_app/new-svelte.html -->
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <script type="module" src="{% static 'notes/bundle.js' %}"></script>
    <link rel='stylesheet' href="{% static 'notes/bundle.css' %}">
    <link rel='stylesheet' href="{% static 'css/global.css' %}">
</head>

<body>
    <noscript>ah shucks. you should see a svelte component, 
not this message :/ enable javascript if you wanna use svelte</noscript>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

If you copy pasted the above code you should be seeing your svelte app when you go to localhost/your_app/new/svelte.

Serving Static Files in Django

You may need to add 'django.contrib.staticfiles' to your settings.py INSTALLED_APPS[] but this is worth reading: https://docs.djangoproject.com/en/3.1/howto/static-files/

Sources:

This article was instrumental: https://dev.to/ashraf_zolkopli/django-svelte-best-dev-experience-dx-1848

But the raw source is here: https://gitlab.com/mdpb/svelte-django-example

Top comments (4)

Collapse
 
ashraf_zolkopli profile image
ashrafZolkopli

Hey Max,

Thanks for the shoutout and Amazing post... I'll keep in mind when ever I want to use Svelte for my Django Page. Bookmarked...

I think the next thing we should now think about is how Svelte can be use for MPA
Multiple Page Application. This way we can run one Svelte instance then we could just make multiple pages.

Collapse
 
zodman profile image
Andres 🐍 in 🇨🇦

check my connector to inertia-django that's will be blowmind!

Collapse
 
ericchapman profile image
Eric The Coder

Link? I will like to try...

Collapse
 
zodman profile image
Andres 🐍 in 🇨🇦