Skip to content
| Marketplace
Sign in
Visual Studio Code>Programming Languages>Angular Schematic TemplatesNew to Visual Studio Code? Get it now.
Angular Schematic Templates

Angular Schematic Templates

Carlos Morcillo Fernández

|
3 installs
| (1) | Free
Language support for Angular schematic template files: grammar, completion, diagnostics and formatting.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Angular Schematic Templates

Language support for Angular schematic template files, the grammar included: the .ts, .html, .scss and .json files under a schematic's files/ folder, with <%= %> tags inside.

Without it, VS Code opens those files as plain TypeScript or HTML. The tags break the highlighting and the TypeScript service reports them as errors.

Features

  • Highlighting of the host language and of the code inside <%= %>, <%- %>, <% %> and <%# %>, including tags inside strings, attributes and CSS values.
  • No false errors: templates move to their own language (Schematic Template (TypeScript) and so on), which the built-in TypeScript, HTML and CSS services leave alone.
  • Snippets: tpl-out, tpl-escape, tpl-code, tpl-comment, tpl-for, tpl-if, tpl-ifelse and tpl-call.
  • Typing <% closes the tag for you.
  • Formatting with the project's own Prettier and config, for TypeScript, JavaScript, HTML (Angular parser), SCSS and CSS templates. The tags are hidden while Prettier runs and put back untouched. If a tag would be lost or moved, or Prettier cannot parse the template, the file is left as it is and the status bar says why. In HTML templates the content of a <% for %> or <% if %> block is indented one level deeper than its tags.

Completion and diagnostics inside the tags

A language server reads the code inside the tags as TypeScript, with the type of the data the template receives. It offers completion, hover, go to definition and real errors there, such as a property the data does not have.

The type is deduced from the schematic factory. The extension looks for the url('./files') call whose folder holds the template, then for the call that passes the data to it: template(vars), applyTemplates(vars) or a project function listed in schematicTemplates.contextFunctions. The data needs a named, exported type (an interface or type alias). Anonymous object types give the property names only, and open types such as Record<string, any> count as untyped.

When the type cannot be deduced, the first line of the template shows why, and there are no errors inside the tags. The quick fix on that warning opens a list of exported types, the ones of the same schematic first, and writes a header like this one:

<%# @context ../types/page-context#PageContext %>

The header must be on the first line, and it always wins over the deduction. The template engine drops it as a comment, so it never reaches the generated code.

How templates are detected

A file is a template when it sits, at any depth, under a template folder (files by default) whose parent directory is a schematic. A directory counts as a schematic when:

  • a factory in the workspace collection points into it. The collection comes from the schematics field of package.json, or from any collection.json outside node_modules; or
  • it has an index.ts or index.js, which covers schematics registered in code rather than in a collection.

Only templates that contain tags switch to a schematic language. A template without tags is ordinary host code and keeps its language, formatter and tools; it switches as soon as a tag is typed. The file keeps its name, so nothing changes for the schematics build. A trailing .template or .ejs is ignored when choosing the host language, so x.service.ts.ejs is TypeScript. Other file types (Markdown, YAML...) switch to Schematic Template (Plain Text).

Settings

Setting Default Purpose
schematicTemplates.templateFolders ["files"] Folder names that hold templates
schematicTemplates.languageServer.enabled true Completion, hover and diagnostics inside the tags. Turn it off to keep only highlighting, snippets and formatting
schematicTemplates.contextFunctions [] Project functions that receive a template's data, besides template() and applyTemplates(). Each entry is { "name", "argument" }, plus "property" when the data travels inside an options object
schematicTemplates.format.respectPrettierIgnore false Skip templates listed in .prettierignore when formatting. Projects usually list templates there only because plain Prettier cannot parse them

Known limitations

  • A tag in an unusual spot, such as half of an HTML attribute name, can confuse the host highlighting for the rest of that construct.
  • A name fragment glued to a tag, such as Widget in Widget<%= id %>, shows in the default text colour. Host rules would otherwise read Widget< as the start of a generic type and swallow the tag.
  • Right after a template opens, the host language's errors can show for a moment before the language switch clears them.
  • Inside the tags the highlighting covers a flat subset of JavaScript: keywords, strings, numbers, calls and property access. Regular expression literals are not recognised.
  • Formatting never touches the code inside the tags. A template whose host code is only valid once the tags run (for example, object properties in two branches with no comma between them) cannot be parsed and is left unformatted. JSON templates are not formatted.
  • Templates excluded from every tsconfig.json are checked with TypeScript's default options, so path aliases (@app/...) in the modules that declare their data types do not resolve. Relative imports work. A tsconfig.json that includes the templates fixes it.
  • The deduction follows url() with a literal folder or a const holding one. A folder built at run time, or a template source passed through a helper that is not listed in contextFunctions, cannot be traced; the warning says so and the header is the way out.
  • After a TypeScript file is created or deleted, an error inside a tag can stay until the next change. Editing an existing file updates open templates straight away.
  • A tag glued to an element name, as in <div<% if (open) { %> class="dropdown"<% } %>>, gets a space before it when formatted. The generated HTML means the same.
  • From a template, only the names it declares itself, such as a loop variable or a const, can be renamed. Context properties, their nested properties and imported names are renamed where they are declared.
  • Find References from a template lists the template and the property in the type, but not other templates, nor the project code when the templates are outside every tsconfig.json.
  • Go to definition on a context property does nothing when the type is only known by its property names (an anonymous type, with no named type to open).

Development

npm install
npm test                  # unit and grammar tests, on the tsc output in out/
npm run bundle            # bundles the extension and the language server into dist/ with esbuild
npm run test:integration  # compiles, bundles and runs the suite inside a downloaded VS Code, on a copy of the fixture
SCHEMATIC_TEMPLATES_SERVER_OFF=1 npm run test:integration  # same, with the language server off
npm run package           # bundles, then builds the .vsix from dist/ without node_modules

The extension runs from dist/, so run npm run bundle after a change before pressing F5. TypeScript is not bundled: the language server loads the project's own copy, or the one inside VS Code.

The grammar tests use the host grammars of a local VS Code install. Set VSCODE_BUILTIN_EXTENSIONS to another extensions folder if VS Code is not in /Applications.

Press F5 to try the extension in an Extension Development Host. To install a build, run Extensions: Install from VSIX... and pick the .vsix.

Licence

MIT.

The icon adapts the Angular logo, which Google publishes under CC BY 4.0 in the Angular press kit. This extension is not affiliated with or endorsed by the Angular team.

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft