Django-components provides a seamless integration with HTML fragments (HTML over the wire), whether you're using HTMX, AlpineJS, or vanilla JavaScript.
When you define a component that has extra JS or CSS, and you use django-components to render the fragment, django-components will:
Automatically load the associated JS and CSS
Ensure that JS is loaded and executed only once even if the fragment is inserted multiple times
Info
What are HTML fragments and "HTML over the wire"?
It is one of the methods for updating the state in the browser UI upon user interaction.
How it works is that:
User makes an action - clicks a button or submits a form
The action causes a request to be made from the client to the server.
Server processes the request (e.g. form submission), and responds with HTML of some part of the UI (e.g. a new entry in a table).
A library like HTMX, AlpineJS, or custom function inserts the new HTML into the correct place.
Django-components provides a seamless integration with HTML fragments with AJAX (HTML over the wire), whether you're using jQuery, HTMX, AlpineJS, or vanilla JavaScript.
When you define a component that has extra JS or CSS, and you use django-components to render the fragment, django-components will:
Automatically load the associated JS and CSS
Ensure that JS is loaded and executed only once even if the fragment is inserted multiple times
Info
What are HTML fragments and "HTML over the wire"?
It is one of the methods for updating the state in the browser UI upon user interaction.
How it works is that:
User makes an action - clicks a button or submits a form
The action causes a request to be made from the client to the server.
Server processes the request (e.g. form submission), and responds with HTML of some part of the UI (e.g. a new entry in a table).
A library like HTMX, AlpineJS, or custom function inserts the new HTML into the correct place.
Fragment mode assumes that the main HTML has already been rendered and loaded on the page. The component renders HTML that will be inserted into the page as a fragment, at a LATER time:
JS and CSS is not directly embedded to avoid duplicately executing the same JS scripts. So template tags like {% component_js_dependencies %} inside of fragments are ignored.
Instead, django-components appends the fragment's content with a JSON <script> to trigger a call to its asset manager JS script, which will load the JS and CSS smartly.
The asset manager JS script is assumed to be already loaded on the page.
Fragment strategy assumes that the main HTML has already been rendered and loaded on the page. The component renders HTML that will be inserted into the page as a fragment, at a LATER time:
JS and CSS is not directly embedded to avoid duplicately executing the same JS scripts. So template tags like {% component_js_dependencies %} inside of fragments are ignored.
Instead, django-components appends the fragment's content with a JSON <script> to trigger a call to its asset manager JS script, which will load the JS and CSS smartly.
The asset manager JS script is assumed to be already loaded on the page.
However, there is a problem here - When we call render_dependencies() inside CardActions.render(), we extract and REMOVE the info on components' JS and CSS from the HTML. But the template of CardActions contains no {% component_depedencies %} tags, and nor <head> nor <body> HTML tags. So the component's JS and CSS will NOT be inserted, and will be lost.
However, there is a problem here - When we call render_dependencies() inside CardActions.render(), we extract and REMOVE the info on components' JS and CSS from the HTML. But the template of CardActions contains no {% component_depedencies %} tags, and nor <head> nor <body> HTML tags. So the component's JS and CSS will NOT be inserted, and will be lost.
The rendered HTML may be used in different contexts (browser, email, etc). If your components use JS and CSS scripts, you may need to handle them differently.
render() and render_to_response() accept a deps_strategy parameter, which controls where and how the JS / CSS are inserted into the HTML.
The deps_strategy parameter is set at the root of a component render tree, which is why it is not available for the {% component %} tag.
deps_strategy="fragment" is used when rendering a piece of HTML that will be inserted into a page that has already been rendered with the "document" strategy:
The HTML of fragments is very lightweight because it doesn't include the JS and CSS scripts of the rendered components.
With fragments, even if a component has JS and CSS, you can insert the same component into a page hundreds of times, and the JS and CSS will only ever be loaded once.
This is intended for dynamic content that's loaded with AJAX after the initial page load, such as with jQuery, HTMX, AlpineJS or similar libraries.
Location:
None. The fragment's JS and CSS files will be loaded dynamically into the page.
Included scripts:
A special JSON <script> tag that tells the dependency manager what JS and CSS to load.
This is the same as "simple", but placeholders like {% component_js_dependencies %} and HTML tags <head> and <body> are all ignored. The JS and CSS are always inserted before the rendered content.
This is the same as "simple", but placeholders like {% component_js_dependencies %} and HTML tags <head> and <body> are all ignored. The JS and CSS are always inserted after the rendered content.
html=MyComponent.render(deps_strategy="append")
+
Location:
JS and CSS is always inserted after the rendered content.
\ No newline at end of file
diff --git a/dev/concepts/fundamentals/html_js_css_files/index.html b/dev/concepts/fundamentals/html_js_css_files/index.html
index 5592ff70..59558294 100644
--- a/dev/concepts/fundamentals/html_js_css_files/index.html
+++ b/dev/concepts/fundamentals/html_js_css_files/index.html
@@ -66,7 +66,7 @@
<divclass="card"data-djc-id-c1a2b3cdata-djc-css-d4e5f6><!-- Component content --></div>
-
Insert JS and CSS: After the HTML is rendered, Django Components handles inserting JS and CSS dependencies into the page based on the render type (document, fragment, or inline).
The component's JS script is executed in the browser:
It is executed AFTER the "secondary" JS files from Component.Media.js are loaded.
The script is only executed once, even if there are multiple instances of the component on the page.
Component JS scripts are executed in the order how they appeared in the template / HTML (top to bottom).
You can define the JS directly in your Python code using the js attribute:
classButton(Component):
+
Insert JS and CSS: After the HTML is rendered, Django Components handles inserting JS and CSS dependencies into the page based on the dependencies rendering strategy (document, fragment, or inline).
Do NOT modify HTML / CSS / JS after it has been loaded
django-components assumes that the component's media files like js_file or Media.js/css are static.
If you need to dynamically change these media files, consider instead defining multiple Components.
Modifying these files AFTER the component has been loaded at best does nothing. However, this is an untested behavior, which may lead to unexpected errors.