Skip to main content
The Angular PWA Demo implements a custom routing system with extended route metadata for enhanced navigation capabilities.

Extended route interface

The application extends Angular’s standard Route interface to include additional metadata:
app-routing.module.ts:33-38
export interface _Route extends Route
{  
    id      : number;
    caption : string;
    queryParams : string;
}
This extended interface allows routes to carry presentation metadata (captions) and query parameter identifiers for dynamic content loading.

Route configuration

The application defines 44 routes covering various features:

Home and navigation

app-routing.module.ts:42-44
{  id: 0,  path: 'Home'      , component: HomeWebComponent       , caption: ' Home'  , queryParams : 'PAGE_ANGULAR_DEMO_INDEX' },
{  id: 0,  path: 'Index'     , component: IndexComponent         , caption: ' Index' , queryParams : 'PAGE_HOME_INDEX'         },
{  id: 0,  path:  ''         , component: HomeWebComponent       , caption: ''       , queryParams : '' },
The default route ('') loads the home component, providing a landing page for first-time visitors.

Route component reuse pattern

The application demonstrates an efficient pattern for component reuse:
// Same component, different content via queryParams
{  path: 'GridParam', component: GridParamComponent, 
   caption: ' Curriculum - Angular / Typescript', 
   queryParams : 'PAGE_CURRICULUM_ANGULAR' }

{  path: 'GridParam', component: GridParamComponent, 
   caption: ' Curriculum - Node.js / Javascript', 
   queryParams : 'PAGE_CURRICULUM_NODE_JS' }
This pattern reduces code duplication by using a single component to display multiple content variations based on query parameters.

Route ID assignment

The routing module automatically assigns sequential IDs to routes in the constructor:
app-routing.module.ts:93-104
constructor()
{
    //
    let index : number = 0;
    //
    routes.forEach(element => {
        if (((element.path == '') && (element.caption == ''))==false)
        {
          element.id = ++index;
        }
    });    
}
Routes with both empty path and caption are excluded from ID assignment, as they represent fallback or utility routes.

Router module configuration

The router is configured with the forRoot method:
app-routing.module.ts:87-90
@NgModule({
  imports: [RouterModule.forRoot(routes)], 
  exports: [RouterModule]
})

Router configuration options

While not explicitly shown in the configuration, forRoot can accept additional options:
RouterModule.forRoot(routes, {
  useHash: false,                    // Use path-based routing
  enableTracing: false,              // Debug routing in console
  preloadingStrategy: PreloadAllModules,  // Lazy loading strategy
  scrollPositionRestoration: 'enabled',   // Restore scroll on navigation
  anchorScrolling: 'enabled',            // Enable fragment scrolling
  relativeLinkResolution: 'corrected'    // Fix relative link resolution
})

Hash location strategy

The application uses hash-based routing:
app.module.ts:112
{ provide: LocationStrategy, useClass: HashLocationStrategy }

Why hash location strategy?

Server compatibility

Works with any web server without URL rewrite configuration

Deployment flexibility

Can be deployed to static hosting without server-side routing setup

Legacy support

Compatible with older browsers and hosting environments

Bookmark friendly

URLs with hash fragments work consistently across all servers
Hash strategy creates URLs like example.com/#/about instead of example.com/about. While less aesthetic, it provides maximum compatibility.

Wildcard route

The last route captures all unmatched URLs:
app-routing.module.ts:84
{  id: 0,  path: '**'  , component: PageNotFoundComponent  , caption: ''  , queryParams : '' },
The wildcard route (**) must be the last route in the configuration. It acts as a catch-all for undefined paths.
The application supports multiple navigation approaches:
// Navigate to a specific path
this.router.navigate(['/AlgorithmSort']);
// Navigate with query parameters
this.router.navigate(['/GridParam'], {
  queryParams: { pageId: 'PAGE_CURRICULUM_ANGULAR' }
});
// Navigate relative to current route
this.router.navigate(['../sibling'], { relativeTo: this.route });
// Navigate with state data
this.router.navigate(['/details'], {
  state: { data: selectedItem }
});

Route organization summary

The 44 routes are organized into categories:
CategoryRoute CountExample
Home/Core3Home, Index, “
About5SCM, TechnicalSpecs, ContactForm
Algorithms4AlgorithmSort, AlgorithmDijkstra
File Generation4FilesGenerationPDF, Chart
Games7GamesTetris, GamesSudoku
Miscellaneous3Chat, OcrPhotoCapture, FractalDemo
Machine Learning1LinearRegression
Curriculum7CurriculumAngular, various GridParam
Demo Languages6Various GridParam for different tech stacks
Utility3PageUrlList, Landing, **

Next steps

Service architecture

Learn about the service layer and dependency injection

PWA features

Understand Progressive Web App capabilities

Architecture overview

Review the complete architecture

Quick start

Get started with development

Build docs developers (and LLMs) love