.html file in Aero is a template. The same syntax — { } expressions, directives, <script is:build> — works in all of them. The difference is where the file lives and what role it plays:
Template auto-import
By default (templateAutoImport: true), Aero resolves -layout and -component tags from your project tree. You do not need a matching import in <script is:build> for each tag. The build, aero check, and the VS Code extension use the same rules: tag base name → client/layouts/*.html or client/components/**/*.html.
Still import explicitly: @content/*, npm packages, .ts / .js modules, and assets (@images/*, etc.).
When to add an explicit template import:
- Override — pin a non-default file for the same binding (e.g.
import footer from '@components/theme/footer.html'for<footer-component />). - Disambiguation — two files share a basename (e.g.
components/toggle.htmlandcomponents/theme/toggle.html); Aero errors until you import one path explicitly. - Opt-out — set
templateAutoImport: falseinaero.config.tsto require imports for every layout/component (legacy behaviour).
demo-list-component maps to binding demoList and file **/demo-list.html under components. Layout tags only search client/layouts/ (non-recursive); component tags search client/components/ recursively.
Pages
Every.html file in client/pages/ becomes a route. index.html maps to /, about.html maps to /about. See Routing for dynamic routes and getStaticPaths.
client/pages/about.html
Components
Components are.html files in client/components/. Use them as custom elements with the -component suffix; no import is required unless you are overriding or disambiguating (see Template auto-import):
client/components/greeting.html
client/pages/index.html
Explicit imports use the
.html extension: import greeting from '@components/greeting.html'.
When you add one, it overrides auto-import for that binding.Props
Pass data to a component via attributes. Use{ } for dynamic values:
Aero.props:
props="{ ...obj }" to pass every key as a separate prop:
/>) when a component has no slot content. Use opening and closing tags to pass children into its <slot>:
Layouts
Layouts are.html files in client/layouts/ that wrap page content. Use <slot /> to mark where the content goes:
client/layouts/base.html
client/pages/about.html
Nested layouts
A layout can use another layout. Content flows from page to inner layout to outer layout:client/layouts/docs.html
Named slots
Define named slots with thename attribute. Pages target them with slot:
client/layouts/base.html
client/pages/home.html
Expressions
Wrap any JavaScript expression in single braces to interpolate it into text or attributes:raw() for intentional unescaped HTML:
Loops
Usefor (or for) with a for…of expression to repeat an element:
index, first, last, and length as automatic variables.
Conditionals
Useif, else-if, and else as attributes:
Switch / case
Match a value against multiple alternatives:Wrapperless output with <template>
Put a directive on <template> to emit only the children without a wrapper element:
if, for, and switch. It is especially useful inside <table> or <select> where an extra <div> would be invalid.
All directive attributes also accept a
data- prefix for strict HTML spec compliance: for,
if, else, etc.