--- title: Defining HTML / JS / CSS files weight: 8 --- django_component's management of files builds on top of [Django's `Media` class](https://docs.djangoproject.com/en/5.0/topics/forms/media/). To be familiar with how Django handles static files, we recommend reading also: - [How to manage static files (e.g. images, JavaScript, CSS)](https://docs.djangoproject.com/en/5.0/howto/static-files/) ## Defining file paths relative to component or static dirs As seen in the [getting started example](#create-your-first-component), to associate HTML/JS/CSS files with a component, you set them as `template_name`, `Media.js` and `Media.css` respectively: ```py # In a file [project root]/components/calendar/calendar.py from django_components import Component, register @register("calendar") class Calendar(Component): template_name = "template.html" class Media: css = "style.css" js = "script.js" ``` In the example above, the files are defined relative to the directory where `component.py` is. Alternatively, you can specify the file paths relative to the directories set in `COMPONENTS.dirs` or `COMPONENTS.app_dirs`. Assuming that `COMPONENTS.dirs` contains path `[project root]/components`, we can rewrite the example as: ```py # In a file [project root]/components/calendar/calendar.py from django_components import Component, register @register("calendar") class Calendar(Component): template_name = "calendar/template.html" class Media: css = "calendar/style.css" js = "calendar/script.js" ``` NOTE: In case of conflict, the preference goes to resolving the files relative to the component's directory. ## Defining multiple paths Each component can have only a single template. However, you can define as many JS or CSS files as you want using a list. ```py class MyComponent(Component): class Media: js = ["path/to/script1.js", "path/to/script2.js"] css = ["path/to/style1.css", "path/to/style2.css"] ``` ## Configuring CSS Media Types You can define which stylesheets will be associated with which [CSS Media types](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_media_queries/Using_media_queries#targeting_media_types). You do so by defining CSS files as a dictionary. See the corresponding [Django Documentation](https://docs.djangoproject.com/en/5.0/topics/forms/media/#css). Again, you can set either a single file or a list of files per media type: ```py class MyComponent(Component): class Media: css = { "all": "path/to/style1.css", "print": "path/to/style2.css", } ``` ```py class MyComponent(Component): class Media: css = { "all": ["path/to/style1.css", "path/to/style2.css"], "print": ["path/to/style3.css", "path/to/style4.css"], } ``` NOTE: When you define CSS as a string or a list, the `all` media type is implied. ## Supported types for file paths File paths can be any of: - `str` - `bytes` - `PathLike` (`__fspath__` method) - `SafeData` (`__html__` method) - `Callable` that returns any of the above, evaluated at class creation (`__new__`) ```py from pathlib import Path from django.utils.safestring import mark_safe class SimpleComponent(Component): class Media: css = [ mark_safe(''), Path("calendar/style1.css"), "calendar/style2.css", b"calendar/style3.css", lambda: "calendar/style4.css", ] js = [ mark_safe(''), Path("calendar/script1.js"), "calendar/script2.js", b"calendar/script3.js", lambda: "calendar/script4.js", ] ``` ## Path as objects In the example [above](#supported-types-for-file-paths), you could see that when we used `mark_safe` to mark a string as a `SafeString`, we had to define the full `' ) @register("calendar") class Calendar(Component): template_name = "calendar/template.html" def get_context_data(self, date): return { "date": date, } class Media: css = "calendar/style.css" js = [ # ', self.absolute_path(path) ) return tags @register("calendar") class Calendar(Component): template_name = "calendar/template.html" class Media: css = "calendar/style.css" js = "calendar/script.js" # Override the behavior of Media class media_class = MyMedia ``` NOTE: The instance of the `Media` class (or it's subclass) is available under `Component.media` after the class creation (`__new__`).