In this tutorial, we will show to implement the Fragment URL in Angular 8 i.e. nothing but the link which jumps to the content which contains the id mention in the fragment of an angular router.
Topics
let’s create the app routing assume wich display the home page content on the /content
url. i.e on /content
url our main app.component.ts / .html data will be displayed .
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule, Routes, ExtraOptions } from '@angular/router';
import { AppComponent } from '../app.component';
const routerOptions: ExtraOptions = {
scrollPositionRestoration: 'enabled',
anchorScrolling: 'enabled',
scrollOffset: [0, 64],
};
const routes: Routes = [
{
path: 'content',
component: AppComponent,
},
{
path: '',
redirectTo: 'content',
pathMatch: 'full'
}
]
@NgModule({
imports: [CommonModule, RouterModule.forRoot(routes, routerOptions)],
exports: [RouterModule]
})
export class AppRoutingModule { }
lets split up the router module parts to make it understand properly.
Router Options
we will create a configuration which will contain options for the router to make our fragment router attribute work.
const routerOptions: ExtraOptions = {
scrollPositionRestoration: 'enabled',
anchorScrolling: 'enabled',
scrollOffset: [0, 64],
};
scrollPositionRestoration: on change of router url the position of the screen will set to the top.
anchorScrolling : When set to ‘enabled’, scrolls to the anchor element when the URL has a fragment. Anchor scrolling is disabled by default.
scrollOffset: Configures the scroll offset the router will use when scrolling to an element.
Set Options forRoot
set the ExtraOptions
to the RouterModule.forRoot()
method.
@NgModule({
imports: [CommonModule, RouterModule.forRoot(routes, routerOptions)], //ExtraOptions
...
})
Routes
as it is mention that we will route our home page on /content
so the routes are declared as:
const routes: Routes = [
{
path: 'content',
component: AppComponent,
},
{
path: '',
redirectTo: 'content', // Empty path will redirect to content route.
pathMatch: 'full'
}
];
Import RoutingModule in AppModule
Now just import the RouterModule file in our main app module file so it can be run thought out the application.
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { HelloComponent } from './hello.component';
import { RouterModule, Router } from '@angular/router';
import { AppRoutingModule } from './app-routing/app-routing.module';
@NgModule({
imports: [ BrowserModule, RouterModule, AppRoutingModule ], // imported AppRoutingModule module
declarations: [ AppComponent, HelloComponent ],
bootstrap: [ AppComponent ],
providers: [ ]
})
export class AppModule { }
Create A Fragment URL in Angular 8
At the final, we will create a markdown which will contain an angular attribute i.e routerLink
and fragment
.
The fragment will contain the id of that section and that ID will use in anchor tag!
Suppose we have array of content
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
name = 'Angular';
ids: Array<String> = ['one', 'two', 'three', 'four']
}
So in our app.component.html we will configure our anchor tags as mention below
<div class="links">
<ul>
<li *ngFor="let link of ids">
<a [routerLink]='"."' [fragment]="link">{{link}}</a>
</li>
</ul>
</div>
and the section with id
attribute will be as follow
<section>
<div class="section" *ngFor="let link of ids" [attr.id]='link' >
<h1>{{link}}</h1>
<div class="content">
<!-- YOUR CONTENT GOES HERE -->
</div>
</div>
</section>
Fragment URL In [innerHTML]
Incase if your markup data are loaded from API and that contain hash content routing i.e fragment URL in [innerHTML]
you can manually replace some URLs to make it work in angular application.
you can see my example the way I implemented it.
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class BlogContentComponent implements OnInit, AfterViewChecked {
@Input()
blog_content: String;
@Input()
slug: String;
constructor() {}
ngOnInit() {}
ngAfterViewChecked() {
if (this.blog_content ) {
const anchors = document.getElementsByTagName('a');
for (let i = 0; i < anchors.length; i++) {
if (anchors[i].hash) { // hash URL
const hash = anchors[i].hash.replace('#', '');
anchors[i].setAttribute('href', `/${this.slug}#${hash}`);
anchors[i].setAttribute('fragment', `${hash}`);
anchors[i].setAttribute('ng-reflect-fragment', `${hash}`);
anchors[i].setAttribute('routerlink', `/${this.slug}`);
anchors[i].setAttribute('ng-reflect-router-link', `/${this.slug}`);
} else if (anchors[i].href.match(environment.site_url_regex)) { // site_url_regex: new RegExp('https://www.geekstrick.com', 'gmi'),
const url = anchors[i].href.replace(environment.site_url, ''); // site_url: 'https://www.geekstrick.com',
anchors[i].setAttribute('href', `${url}`);
anchors[i].setAttribute('routerlink', `${url}`);
anchors[i].setAttribute('ng-reflect-router-link', `${url}`);
}
}
}
}
}
this will conver normal URL to angular router links with fragments.
and html will be same as it is
<article class="article" [innerHTML]="blog_content | safeHtml"></article>