This plugin adds a gohtml filetype, which recognizes .gohtml and
.html.gotmpl file extensions, and configures Tree-sitter to recognize both
Go template and HTML syntaxes. It also helps you configure LSPs for a great
editing experience.
- Requires
- Requires
nvim-treesitter/nvim-treesitter
vim.pack.add {
'https://github.com/nvim-treesitter/nvim-treesitter',
'https://github.com/Xadeck/gohtml.nvim',
}{
'Xadeck/gohtml.nvim',
dependencies = { 'nvim-treesitter/nvim-treesitter' },
ft = { 'gohtml' },
}Ensure that the Tree-sitter parser for gotmpl is installed:
require('nvim-treesitter').install {
'gotmpl',
}Note
This is not a typo: you want the gotmpl parser for Go templates. This plugin
adds a new gohtml language, re-using this parser but with configured
Tree-sitter injections for HTML.
You then just need to require the plugin:
require('gohtml')There is no need to call a setup() function for standard functionality. The
plugin sets itself up automatically the first time a file with the gohtml
filetype is opened. It will display notifications if any problems are detected.
You can pre-emptively run :checkhealth gohtml to diagnose issues and view LSP
recommendations.
The gotmpl parser treats HTML markup as generic text nodes and delegates HTML
parsing via Tree-sitter injections. Neither Neovim nor nvim-treesitter evaluate
fold queries on injected sub-languages (html inside gotmpl). As a result:
- Go template directives like
{{ range .Object }}can fold. - HTML tags cannot fold via Tree-sitter.
Therefore, the plugin sets foldmethod=indent as a local option, overriding
any setting you have - typically foldmethod=expr with
foldexpr=nvim_treesitter#foldexpr().
LSP configuration is optional but strongly recommended for auto-completion and symbol navigation.
- Configure an HTML LSP and a Go template LSP.
- Configure those LSPs to recognize the
gohtmlfiletype.
We recommend html and gopls from the
neovim/nvim-lspconfig plugin.
vim.pack.add {
'https://github.com/neovim/nvim-lspconfig',
}
vim.lsp.enable {
'gopls',
'html',
}To associate these LSPs with gohtml, use Neovim's native
:help lsp-config-merge
mechanism. Add the following two files to your Neovim config directory:
-- .config/nvim/after/lsp/html.lua
return {
filetypes = { 'html', 'gohtml' },
}-- .config/nvim/after/lsp/gopls.lua
return {
filetypes = { 'go', 'gomod', 'gowork', 'gotmpl', 'gohtml' },
settings = {
gopls = {
templateExtensions = { 'gotmpl', 'gohtml' },
},
},
}Important
Ideally, support for .gohtml will be added upstream to
neovim/nvim-lspconfig.
These integrations are optional. You can configure them manually in your
init.lua or call require('gohtml').integrations() to automatically apply all
supported integrations.
The tailwindcss LSP in nvim-lspconfig already includes gohtml in its
default filetypes list—see its
config—so
no extra setup is needed.
If you use alpinejs.nvim,
configure it to recognize gohtml:
vim.pack.add {
'https://github.com/ConnorOnTheWeb/alpinejs.nvim',
}
require('alpinejs').setup {
filetypes = { 'html', 'jinja', 'htmldjango', 'nunjucks', 'gohtml' },
}If you use stevearc/conform.nvim,
configure formatters for gohtml:
require('conform').setup {
formatters_by_ft = {
lua = { 'stylua' },
gohtml = { 'djlint', 'rustywind' },
},
format_on_save = {},
}djlint works well for HTML Go templates, and
rustywind sorts Tailwind CSS classes
consistently.
Note
The Hugo team has developed a new formatter for Go templates: check out
gotmplfmt.
If you use snacks.nvim picker,
enable gohtml symbols in the Tree-sitter picker:
require('snacks').setup {
picker = {
enabled = true,
sources = {
treesitter = {
filter = {
gohtml = true,
},
},
},
},
}Run :checkhealth gohtml to verify your configuration.
(Source: Gemini discussion)
- JetBrains (GoLand / WebStorm / IntelliJ): JetBrains explicitly maps
.gohtmlby default to Go template files. They recommend.gohtmlbecause it tells the IDE to parse both HTML markup and Go template control structures ({{ if ... }}) simultaneously. - VS Code Extensions: Popular Go/HTML extensions (such as
vscode-gocommunity tooling and Go Template syntax extensions) adopt.gohtmlto distinguish standard HTML from templated HTML. - Legacy Editors (Atom, GoSublime, TextMate): Early Go Web developers
created syntax definitions mapping
.gohtmlto Go'shtml/templateengine to avoid breaking standard HTML grammar rules.
- Web Frameworks & Libraries: Frameworks like GoFiber, Hugo (for partials),
and community cheatsheets showcase
.gohtmlas the clearest convention forhtml/templateassets. - Formatter/Linter Tooling: Formatter integrations (like Prettier plugins
for Go templates) often rely on
.gohtmlto apply dual-language formatting rules without corrupting plain HTML files.
