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
- Build your svelte component(s) locally.
- Compile your svelte page(s) and send them to the
static
directory for your Django app. - 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>
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'),
]
...
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))
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>
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)
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.
check my connector to inertia-django that's will be blowmind!
Link? I will like to try...
pypi.org/project/inertia-django/0....