# How to Use HTML Templates with Custom Delimiters in Gin

> Easily customize HTML template delimiters in your Gin web applications. Learn to change default {{ and }} to any characters with Engine Delims for dynamic templating.

- Repository: [Gin-Gonic/gin](https://github.com/gin-gonic/gin)
- Tags: how-to-guide
- Published: 2026-02-27

---

**You can change Gin’s default template delimiters by calling `Engine.Delims(left, right)` before loading templates, which updates the engine’s internal `delims` field and applies the new delimiters to all subsequent `LoadHTMLGlob`, `LoadHTMLFiles`, or `LoadHTMLFS` calls.**

Gin’s templating subsystem is built on Go’s standard `html/template` package, which defaults to the standard `{{` and `}}` delimiters. When building applications that use JavaScript frameworks like Vue or Angular—which often conflict with these markers—you can configure custom delimiters globally for the entire router as implemented in the `gin-gonic/gin` source code.

## Setting Global Delimiters

Call `Engine.Delims(left, right)` immediately after creating your router instance and before loading any template files. This method stores the custom delimiter pair in the engine’s `delims` field, which defaults to `render.Delims{Left: "{{", Right: "}}"}`` according to the source in [`gin.go`](https://github.com/gin-gonic/gin/blob/main/gin.go) [L223](https://github.com/gin-gonic/gin/blob/master/gin.go#L223).

The implementation in [`gin.go`](https://github.com/gin-gonic/gin/blob/main/gin.go) [L58-L62](https://github.com/gin-gonic/gin/blob/master/gin.go#L58-L62) simply assigns the provided strings to the engine’s configuration:

```go
r := gin.Default()
r.Delims("{[{", "}]}")  // Change delimiters globally
r.LoadHTMLGlob("templates/*.tmpl")

```

Once set, these delimiters persist for the lifetime of the engine instance and automatically propagate to every template parsing operation.

## Loading Templates with Custom Delimiters

Gin applies the stored delimiter configuration during the template parsing phase. Whether you load templates via glob patterns, specific file lists, or embedded filesystems, the engine forwards your custom delimiters to the underlying `html/template` parser.

### LoadHTMLGlob

When using `LoadHTMLGlob`, Gin creates a new template instance and immediately applies the custom delimiters before parsing the glob pattern. The implementation in [`gin.go`](https://github.com/gin-gonic/gin/blob/main/gin.go) [L70-L76](https://github.com/gin-gonic/gin/blob/master/gin.go#L70-L76) executes:

```go
template.New("").Delims(left, right).ParseGlob(pattern)

```

### LoadHTMLFiles

For explicit file lists, the `LoadHTMLFiles` method in [`gin.go`](https://github.com/gin-gonic/gin/blob/main/gin.go) [L86-L94](https://github.com/gin-gonic/gin/blob/master/gin.go#L86-L94) passes the engine’s stored delimiter values to `ParseFiles`:

```go
template.New("").Delims(engine.delims.Left, engine.delims.Right).ParseFiles(files...)

```

### LoadHTMLFS

When loading from an embedded filesystem (Go 1.16+), `LoadHTMLFS` in [`gin.go`](https://github.com/gin-gonic/gin/blob/main/gin.go) [L98-L106](https://github.com/gin-gonic/gin/blob/master/gin.go#L98-L106) applies the same delimiter configuration:

```go
template.New("").Delims(engine.delims.Left, engine.delims.Right).ParseFS(...)

```

## Rendering Templates

After loading templates with custom delimiters, render them normally using `c.HTML()`. The parser has already internalized your delimiter configuration, so template files should use the new markers exclusively.

```go
r.GET("/hello/:name", func(c *gin.Context) {
    c.HTML(http.StatusOK, "hello.tmpl", gin.H{
        "Name": c.Param("name"),
    })
})

```

## Debug Mode Behavior

In development mode (`gin.IsDebugging()` returns `true`), Gin uses the `render.HTMLDebug` renderer, which stores the delimiter configuration alongside template source information. As implemented in [`render/html.go`](https://github.com/gin-gonic/gin/blob/main/render/html.go) [L75-L80](https://github.com/gin-gonic/gin/blob/master/render/html.go#L75-L80), this renderer parses template files on each request using your custom delimiters, ensuring changes are reflected without server restarts.

## Complete Working Example

The following example demonstrates a full implementation using `{[{` and `}]}` as custom delimiters to avoid conflicts with frontend frameworks.

**main.go:**

```go
package main

import (
	"net/http"

	"github.com/gin-gonic/gin"
)

func main() {
	// Create router with default middleware
	r := gin.Default()

	// Set custom delimiters before loading templates
	r.Delims("{[{", "}]}")

	// Load templates that use the new delimiters
	r.LoadHTMLGlob("templates/*.tmpl")

	// Define handler
	r.GET("/hello/:name", func(c *gin.Context) {
		c.HTML(http.StatusOK, "hello.tmpl", gin.H{
			"Name": c.Param("name"),
		})
	})

	r.Run(":8080")
}

```

**templates/hello.tmpl:**

```tmpl
<h1>Hello {[{ .Name }]}!</h1>

```

Visiting `http://localhost:8080/hello/gin` outputs:

```html
<h1>Hello gin!</h1>

```

## Summary

- **Call `Engine.Delims(left, right)`** before loading templates to set global delimiters in [`gin.go`](https://github.com/gin-gonic/gin/blob/main/gin.go).
- **All loading methods** (`LoadHTMLGlob`, `LoadHTMLFiles`, `LoadHTMLFS`) automatically forward your custom delimiters to the `html/template` parser.
- **Template files** must use your custom delimiters (e.g., `{[{ .Var }]}` instead of `{{ .Var }}`).
- **Debug mode** re-parses templates with your delimiters on every request for rapid development.

## Frequently Asked Questions

### Can I set different delimiters for individual templates instead of globally?

No, the `gin-gonic/gin` engine stores delimiters in a single `delims` field at the router level as defined in [`gin.go`](https://github.com/gin-gonic/gin/blob/main/gin.go) [L223](https://github.com/gin-gonic/gin/blob/master/gin.go#L223). All templates loaded through that engine instance share the same delimiter configuration. To use different delimiters for specific templates, you must create separate `Engine` instances or manually parse templates outside of Gin’s built-in loader.

### What delimiter characters are valid in Gin?

Gin accepts any string values for left and right delimiters through `Engine.Delims()`, passing them directly to Go’s `html/template.Delims()` method. Valid delimiters must not contain whitespace and should be distinct from content in your templates. Common alternatives include `{[{` and `}]}` for Vue.js compatibility, or `<%` and `%>` for ERB-style syntax.

### Do custom delimiters affect JSON or XML rendering in Gin?

No, delimiter configuration only affects the HTML template rendering system. The `Delims` field is used exclusively by the HTML rendering logic in [`render/html.go`](https://github.com/gin-gonic/gin/blob/main/render/html.go) and methods like `LoadHTMLGlob`. JSON, XML, and other response formats rendered via `c.JSON()` or `c.XML()` operate independently of template delimiter settings.

### Why does my template show literal delimiter text instead of rendered values?

This occurs when the delimiters in your template files do not match the delimiters set via `Engine.Delims()`. Ensure you call `r.Delims()` **before** `r.LoadHTMLGlob()` or other loading methods, and verify that your `.tmpl` files use the exact left and right strings you specified. In debug mode, Gin re-parses templates on each request, so mismatches are easier to spot without server restarts.