diff --git a/README.md b/README.md
index 66fcd992..c5a0389d 100644
--- a/README.md
+++ b/README.md
@@ -177,6 +177,68 @@ Or as Observable:
```angular2html
isLoggedIn$ = this.store.select(selectIsLoggedIn);
```
+### Automatic assets public path (`assets/...`)
+
+If your custom module/add-on is hosted under a dynamic base URL, plain template URLs like:
+
+```html
+
+```
+may break, because the browser resolves them relative to the host page.
+
+To fix this, we provide:
+
+src/app/services/assets-public-path.directive.ts
+
+This directive automatically rewrites any src / href that starts with assets/ (or /assets/) to:
+
+```js
+__webpack_public_path__ + 'assets/...'
+```
+Import the directive in a component (Standalone)
+Add the directive to the component imports:
+
+```js
+import { CommonModule } from '@angular/common';
+import { Component } from '@angular/core';
+import { AssetsPublicPathDirective } from '../services/assets-public-path.directive';
+
+@Component({
+ selector: 'custom-example',
+ standalone: true,
+ templateUrl: './example.component.html',
+ styleUrls: ['./example.component.scss'],
+ imports: [CommonModule, AssetsPublicPathDirective],
+})
+export class ExampleComponent {}
+```
+If the component is not standalone (NgModule-based), import and export the directive from a shared module, and include that module where your components are declared.
+
+Use it in HTML
+After the directive is imported, you can use plain assets/... paths in templates:
+
+
+```html
+
+
+
+
+
+
+
+Help
+```
+Supported attributes/elements (common cases):
+
+img[src]
+
+source[src]
+
+script[src]
+
+link[href]
+
+a[href]
### Accessing app router
diff --git a/src/app/services/assets-public-path.directive.ts b/src/app/services/assets-public-path.directive.ts
new file mode 100644
index 00000000..c833e615
--- /dev/null
+++ b/src/app/services/assets-public-path.directive.ts
@@ -0,0 +1,44 @@
+import { Directive, ElementRef, Input, OnChanges, Renderer2 } from '@angular/core';
+
+declare const __webpack_public_path__: string;
+
+@Directive({
+ selector: 'img[src],source[src],link[href],script[src],a[href]',
+ standalone: true,
+})
+export class AssetsPublicPathDirective implements OnChanges {
+ @Input() src?: string;
+ @Input() href?: string;
+
+ constructor(private el: ElementRef, private r: Renderer2) {}
+
+ ngOnChanges(): void {
+ // Handle [src] / src and [href] / href
+ const tag = (this.el.nativeElement.tagName || '').toLowerCase();
+ const attr = tag === 'link' || tag === 'a' ? 'href' : 'src';
+ const val = attr === 'href' ? (this.href ?? this.el.nativeElement.getAttribute('href')) : (this.src ?? this.el.nativeElement.getAttribute('src'));
+
+ if (!val) return;
+
+ const rewritten = this.rewriteIfAssets(val);
+ if (rewritten !== val) {
+ this.r.setAttribute(this.el.nativeElement, attr, rewritten);
+ }
+ }
+
+ private rewriteIfAssets(url: string): string {
+ // Don’t touch absolute URLs, data:, blob:, etc.
+ if (/^(https?:)?\/\//i.test(url) || /^data:|^blob:/i.test(url)) return url;
+
+ // Normalize
+ const clean = url.startsWith('/') ? url.slice(1) : url;
+
+ if (clean.startsWith('assets/')) {
+ const base = (typeof __webpack_public_path__ === 'string' ? __webpack_public_path__ : '') || '';
+ const baseFixed = base && !base.endsWith('/') ? base + '/' : base;
+ return baseFixed + clean;
+ }
+
+ return url;
+ }
+}