Skip to main content

Render once

If you need to render something to the page once per page, you can create a *OnceHandler with templ.NewOnceHandler() and use its Once() method.

The *OnceHandler.Once() method ensures that the content is only rendered once per distinct context passed to the component's Render method, even if the component is rendered multiple times.

Example​

The hello JavaScript function is only rendered once, even though the hello component is rendered twice.

warning

Dont write @templ.NewOnceHandle().Once() - this creates a new *OnceHandler each time the Once method is called, and will result in the content being rendered multiple times.

component.templ
package once

var helloHandle = templ.NewOnceHandle()

templ hello(label, name string) {
@helloHandle.Once() {
<script>
function hello(name) {
alert('Hello, ' + name + '!');
}
</script>
}
<input type="button" value={ label } data-name={ name } onclick="hello(this.getAttribute('data-name'))"/>
}

templ page() {
@hello("Hello User", "user")
@hello("Hello World", "world")
}
Output
<script>
function hello(name) {
alert('Hello, ' + name + '!');
}
</script>
<input type="button" value="Hello User" data-name="user" onclick="hello(this.getAttribute('data-name'))">
<input type="button" value="Hello World" data-name="world" onclick="hello(this.getAttribute('data-name'))">
tip

Note the use of the data-name attribute to pass the name value from server-side Go code to the client-side JavaScript code.

The value of name is collected by the onclick handler, and passed to the hello function.

To pass complex data structures, consider using a data- attribute to pass a JSON string using the templ.JSONString function, or use the templ.JSONScript function to create a templ component that creates a <script> element containing JSON data.

Common use cases​

  • Rendering a <style> tag that contains CSS classes required by a component.
  • Rendering a <script> tag that contains JavaScript required by a component.
  • Rendering a <link> tag that contains a reference to a stylesheet.

Usage across packages​

Export a component that contains the *OnceHandler and the content to be rendered once.

For example, create a deps package that contains a JQuery component that renders a <script> tag that references the jQuery library.

deps/deps.templ
package deps

var jqueryHandle = templ.NewOnceHandle()

templ JQuery() {
@jqueryHandle.Once() {
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
}
}

You can then use the JQuery component in other packages, and the jQuery library will only be included once in the rendered HTML.

main.templ
package main

import "deps"

templ page() {
<html>
<head>
@deps.JQuery()
</head>
<body>
<h1>Hello, World!</h1>
@button()
</body>
</html>
}

templ button() {
@deps.JQuery()
<button>Click me</button>
}