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 type="text/javascript">
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 type="text/javascript">
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>
}