Search code examples
angularangularjsangular-routerangular-hybrid

Can the Angular router be configured to update Angular routes when anchors with local href's are clicked?


I am in the middle of converting an angularjs application to an Angular 9 application. Part of our code is a content management system that loads HTML written and stored elsewhere. This HTML contains anchors which point to views within the app and I'd like for them to open in place and keep the current app state. This does not appear to be the default for Angular 9.

For example, if I have a link that looks like this: <a href="/home">Home</a> embedded in HTML. When that link is clicked, I want the app to change the top-level page to be the one defined by the angular route /home. This appears to have been the default with anguarjs but when I click that link in Angular it changes the whole URL and it appears to refresh the page. This causes me to lose other page state.

Is there a way to make all of the anchors from this externally loaded HTML use the Angular router instead of the browser location? I cannot change the anchor tags to use routerLink which would be the best solution.


Solution

  • After you've inserted the loaded CMS HTML into your page, you could install a click listener on all <a> tags and do the router navigation programmatically.

    Example

    @Component({
        selector: 'app-cms-page',
        templateUrl: './cms-page.component.html',
        styleUrls: ['./cms-page.component.scss']
    })
    export class CmsPageComponent implements OnInit {
    
        constructor(private router: Router, private elRef: ElementRef) {
        }
    
        ngOnInit(): void {
    
            // Load CMS HTML
            const myHTML = '<a href="/home">Home</a>';
    
            // Insert HTML into this component's element
            const el = <HTMLElement> this.elRef.nativeElement;
            el.insertAdjacentHTML('afterbegin', myHTML);
    
            // Install a click listener on all 'a' elements
            el.querySelectorAll('a').forEach(a => {
                a.addEventListener('click', e => {
    
                    // Prevent the browser from performing any further actions
                    e.stopPropagation();
                    e.preventDefault();
    
                    // Parse the URL to extract the path
                    const url = new URL(a.href);
    
                    // Navigate to the Angular route
                    this.router.navigate([ url.pathname ]);
                });
            });
        }
    }