ilikerobots / cookiecutter-vue-django

Vue 3 + Vite + Django with no compromises. Use Vue SFCs directly in Django Templates, DRF not required.
BSD 3-Clause "New" or "Revised" License
204 stars 23 forks source link

How to handle static images/svg? #86

Closed AMR1798 closed 10 months ago

AMR1798 commented 10 months ago

I'm having issues post build. The static image/icons i referenced in vue is not loading properly and served as "script" type.

Here's the example part of the code.

image

Both of the images/svg resides in static folder of django as i am having trouble to have it served using vite dev server during development. Serving it with dev = True is working fine but after i build the frontend and serve it together with django with VUE_FRONTEND_USE_DEV_SERVER = False set, it will produce the error as below:

image

To handle this, should i:

  1. keep the static images inside vue_frontend and export it upon build? if so, how do i make it so that it serves using :5173 on development instead of :8000 (django)? or
  2. keep the static inside django, but how do i make sure the static are served as image type?

I prefer to have frontend related items to be in vue folder but i'm open to any suggestions for this to work.

AMR1798 commented 10 months ago

Update:

Decided to use data-django-slot in django template then specify v-html in .vue. It works and the static image are now loaded properly through django.

Will keep this issue open to see if anyone else have other methods on how to tackle this issue.

ilikerobots commented 10 months ago

@AMR1798 : awesome, great idea. Another possible way would be to pass the static url from Django to Vue using provide/inject. The 'vue_provide' template tag in django-vue-utilities automates the provide side, and then on the vue side you can inject by name. Then in your image urls, bind to a computed asset url that prefixes the asset path with this injected static prefix.

AMR1798 commented 10 months ago

@ilikerobots thank you for the reply. the vue_provide method works for me. I also found another way for others who want their assets to be in the frontend folder, i set this in the django settings

# in base.py
# MEDIA
# ------------------------------------------------------------------------------
# https://docs.djangoproject.com/en/dev/ref/settings/#media-root
MEDIA_ROOT = str(FRONTEND_DIR / "vue_frontend/public/media")
# https://docs.djangoproject.com/en/dev/ref/settings/#media-url
MEDIA_URL = "/media/"
# in local.py
if VUE_FRONTEND_USE_DEV_SERVER:
    # ASSETS
    # ------------------------------------------------------------------------------
    # https://docs.djangoproject.com/en/dev/ref/settings/#media-root
    ASSET_ROOT = str(FRONTEND_DIR / "vue_frontend/src")
    # https://docs.djangoproject.com/en/dev/ref/settings/#media-url
    ASSET_URL = "/src/"
else:
    # ASSETS
    # ------------------------------------------------------------------------------
    # https://docs.djangoproject.com/en/dev/ref/settings/#media-root
    ASSET_ROOT = str(APPS_DIR / "static/vue/assets")
    # https://docs.djangoproject.com/en/dev/ref/settings/#media-url
    ASSET_URL = "/assets/"
# in config urls.py
urlpatterns = [
    # urls here
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) + static(settings.ASSET_URL, document_root=settings.ASSET_ROOT) # static() would only work for local dev

In production, we'd need to set both /media and /assets to point to their respective folders in nginx. It's not the cleanest option but works for me.

I'll be closing this issue for now. Thank you 🙇‍♂️