Using Prettier with Twig in VS Code

I've been formatting code by hand in VSCode for months because the twig auto-formatting was completely broken. Here's how I got it working at last!

Posted 8th July 2020 • #development

UPDATE 7th March 2022: It looks like the Prettier for Melody plugin is abandoned. Unfortunately I can't find any other alternatives right now, but please let me know if you spot any Prettier plugins that work with Twig. The article below should still work, but I'm finding it to be more and more buggy over time.

This article is about how to get code formatting working for Twig in Visual Studio Code. You'll need these:

If you're managing your project with npm, you can add these lines to package.json, then run npm install from the command line to install them in your project.

"devDependencies": {
  "prettier": "2.0.5",
  "prettier-plugin-twig-melody": "^0.4.6"
},

The first thing you'll want to do is define how Prettier should format your code. You'll do this by adding a .prettierrc.json file in the root of your project. The Melody plugin also adds some useful options for Twig files:

{
	"tabWidth": 3,
	"useTabs": true,
	"semi": false,
	"singleQuote": true,
	"twigPrintWidth": 120,

	"twigMultiTags": [
		"nav,endnav",
		"switch,case,default,endswitch",
		"ifchildren,endifchildren",
		"cache,endcache",
		"js,endjs"
	]
}

You can also specify ignore rules by creating a .prettierignore file in the root of your project, which uses the gitignore syntax. These only take effect if you're running Prettier from the command line to format your whole project at once.

# COMPOSER
/vendor

# CRAFT STORAGE
/craft/storage/*
/storage/*

# Public
/public/*

# BUILD FILES
/bower_components/*
/node_modules/*
/build/*
/yarn-error.log

You should also set up VS Code to format files on save, set the default formatter, and add some default configuration.

{
	// Make VS Code format files when you save them automatically
	"editor.formatOnSave": true,

	// Set the default code formatter
	"editor.defaultFormatter": "esbenp.prettier-vscode",
	"[javascript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },

	// Set up some defaults
	"prettier.disableLanguages": ["html"],
	"prettier.tabWidth": 3,
	"prettier.useTabs": true,
	"prettier.singleQuote": true,
}

And that's it! Your twig files will now be automatically formatted when you save them.

If you want to format everything at once, you can also run Prettier on the whole template directory by running npx prettier --write "templates/**/*.twig"

If you run into parser errors, you may find it's because the plugin doesn't support inline{% if %} statements within HTML tags. To get around this, you'll need to use the ternary conditional syntax within html tags. See this GitHub issue for more info.

There are still some things that don't get formatted correctly with this setup. Notably, using things like Craft's JavaScript tag in twig files using {% js %} will format the JavaScript incorrectly and probably break it (especially if there are comments in it). The Melody plugin comes with a useful feature for dealing with this; and lets you wrap any code you don't want to format with two comments:

{# prettier-ignore-start #} and {# prettier-ignore-end #}

Doing that will ignore the section inside those comments, but still format everything else correctly on save.

Want to know more?

Get in touch