Version 3 - What’s new?
Version 3 marks a significant overhaul and modernization of the Angular Dynamic Hooks library. It is now fully up-to-date with Angular 17+, easier to use and has several completely new features.
The good news: Users of version 2 should only minimally need to adjust their code for the upgrade to version 3. Nevertheless, there are some breaking changes to look out for (see below)
New features
Standalone components
The whole library was converted to the more modern standalone component structure. This makes it future-proof and allows Angular to further optimize package sizes and bundling logic, such as for deferred views.
Less boilerplate
With version 3, configuring global settings/providers has become optional. To get started quickly, the you can pass the content and an array of parsers on each usage of the library individually - nothing else needed.
In addition, you can now use the component classes directly as parsers, as simple as:
parsers = [ExampleComponent];
See the new the Quickstart example for the full code.
SSR-Compatibility
The core functionality of the library has been adjusted to work with Server-Side-Rendering under Angular 17+ out of the box. You can however still implement your own PlatformService, if you have a more specific use-case.
New: HTML as content
Previously, you could only pass strings as the content
input to the library. With v3, you can now also submit HTML elements directly - even document.body
! For example like this:
dynamicHooksService.parse(document.body, parsers).subscribe(result => {
// Do whatever
});
The library will look through all the child elements, search for hooks/selectors and automatically load components into the current browser content.
New: Element hooks
Related to that, you can now look for element hooks in addition to text hooks. Element hooks find and load components into HTML elements (instead of replacing text patterns), so custom parsers can use simple browser methods to find them (querySelectorAll
, etc.).
The standard SelectorHookParser
now also uses the new element hooks under the mood. This has the benefit that it is now able to use proper CSS selectors (.myComponent
) for finding hooks instead of just tag names like before.
New: Standalone mode
With the new standalone mode, you can use the library outside of an Angular app. This means, you can load fully-functional Angular components in non-Angular contexts - for example to add “Angular widgets” to HTML generated by a CMS, static page generators, etc.
All you need is your content and a list of parsers, as always:
import { parse } from 'ngx-dynamic-hooks';
...
parse(content, parsers).then(result => {
// Do whatever
});
New: Single component
In case you just need to load a single dynamic component in your template, a new DynamicSingleComponent was added to make this process as easy as possible.
Breaking changes
DynamicHooksModule
As the library has transitioned to standalone components, trying to use DynamicHooksModule.forRoot()
will throw an error. Instead, use the new provideDynamicHooks
function to create the global settings.
import { ApplicationConfig } from '@angular/core';
import { provideDynamicHooks } from 'ngx-dynamic-hooks';
export const appConfig: ApplicationConfig = {
providers: [
..
provideDynamicHooks({
parsers: [ ... ],
options: { ... }
})
]
};
Additionally, the properties of the settings object have also been simplified:
interface DynamicHooksSettings {
parsers?: HookParserEntry[];
options?: ParseOptions;
inheritance?: DynamicHooksInheritance;
}
Note that using provideDynamicHooks
to create global settings is now completely optional. So you can skip this step completely if you want and instead pass the parsers individually to each DynamicHooksComponent
.
DynamicHooksComponent
To use <ngx-dynamic-hooks>
in your templates, you will now have to import the DynamicHooksComponent
. Simply put it into the imports
field of the component/module that needs it:
@Component({
...
imports: [DynamicHooksComponent]
})
export class YourComponent {
...
}
Child modules
If you were previously using DynamicHooksModule.forChild()
, you can now simply call provideDynamicHooks
again in your child providers to register the child settings. You can do this as deeply nested as you want.
Also, note that DynamicHooksInheritance.LINEAR
is now the default option (instead of ALL
) as its more in line with angular’s default behaviour.
Switch to HTML-based parsing
In v2 of the library, the standard parser to find hooks used regular expressions to find them in the content. In v3, this was replaced by HTML/DOM-based parsing to improve robustness and to make it easier to write custom hooks.
If you encounter any issues with this switch and configurations that previously worked fine now throw errors, you can return to regex-based parsing by enabling it as an option in your SelectorHookParserConfig, like this:
const parsers: HookParserEntry[] = [{
component: ExampleComponent,
parseWithRegex: true
}];
Renamings
Several classes, interfaces, methods etc. were renamed to better reflect their new roles.
OutletComponent
is nowDynamicHooksComponent
OutletService
is nowDynamicHooksService
. Also, the order of the parameters for theparse
method has changed.OutletParseResult
is nowParseResult
and returns more propertiesOutletOptions
is nowParseOptions
HookFinder.findStandaloneHooks
is nowHookFinder.findSingletagHooks
. You can now also just useHookFinder.find
for both singletag or enclosing hooks.
Minor changes
- Traditional text hook parsers from version 2 remain mostly unchanged - with one exception: They will now use
<dynamic-component-anchor>
-elements for components by default. If you want to continue using the component selector, you must specify it manually via thehostElementTag
property. DynamicContentChild.componentSelector
field has been removed. you can mostly accomplish the same viaDynamicContentChild.componentRef.location.nativeElement.tagName
.