register.auto()
Register components dynamically using register.auto(), depending on whether or not it is found in the document or in other component templates.
Syntax
register.auto(find);
Parameters
- find
- A function that finds and returns a URL based on the name of a component. It receives one argument; a name, as a string. This is the .localName of an undefined custom element that was found either on the page or inside another component's template. Then, a URL should be returned (either as a string or as URL object) to pass to
register()
. Alternatively, something falsey may be returned to avoid registration for the given name. The callback fires only once per name.
Return value
None (undefined).
Warning: register.auto() can only be called once; subsequent calls do nothing. Furthermore, the automatic registration cannot be stopped (although an early return can be implemented into the find function).
Details
This function is a much more developer-friendly alternative to component registration. Instead of having to keep track of each component on a page-by-pase basis and registering them using register(), this allows a single snippet to be used across all pages, and without registering unused components. The main downside of register.auto() comes into play when using Yozo in the context of very component-heavy pages; instead of registering all components as soon as the page loads, components used inside other component's templates can only be loaded after the latter has been fetched and parsed. In mostly-static pages, this is usually fine (especially if the parent components behave nicely while not yet defined), but in case there are many (nested) custom elements present and potentially visible on page load, manually listing them and registering using register() may be preferred.
It should be noted that register.auto() looks for elements in the page exactly once on DOMContentLoaded (or immediately when called, if the DOM is already loaded). For component templates, it scans each template once upon component registration (not element creation) meaning any elements registered before calling register.auto() are not scanned. Component templates are scanned in their entirety, disregarding any in-template #if
statements or other inline flow control.
Examples
This site
To get the most out of register.auto(), it is good to structure component files in a way that makes them easy to look up by their name. Usually, that means giving the definition files the same name as the components themselves. In the case of Yozo's website, they are further segmented based on their prefix. Lower level UI components are prefixed ui-, and larger site-wide components (such as the navigation menu or footer) are prefixed with site-. They are then placed in folders by this very prefix. So, for example, the ui-button component is defined in /components/ui/ui-button.yz (in reality, the /components/ part of the URL is slightly different, but static nonetheless). The navigation menu, named site-nav, is defined in /components/site/site-nav.yz. This pattern makes them very easy to look up, and so each page registers its components using
window.yozo.register.auto(name => {
const folder = name.split('-', 1)[0];
return `/components/${folder}/${name}.yz`;
});
Using register.auto() allows for seamless component creation and usage, because once a component file has been created, it is usable immediately. Furthermore, it allows for a simple static site setup that doesn't need to concern itself with what components are used on each page.
Usage notes
Like register(), it is advised to use the full window.yozo.-prefixed expression with register.auto() as opposed to destructuring register, as demonstrated in the example. This is because register itself is somewhat ambiguously named without context. It is also not available by default in component <script>
sections for this very reason.
See also