My Angular 16 app is pure standalone, no ng modules at all.
I configured routes, and when used within components as links (e.g.: routerLink="/team") it routes to the correct page, and the URL changes accordingly.
However, trying to reach a page directly from the URL (for example, by just refreshing the localhost:4200/team
page) - renders the home page. The URL does not even change - /team still appears as the URL, but the rendered page is the home page.
These are the relevant files:
app.component.html:
<app-top-nav></app-top-nav>
<router-outlet></router-outlet>
<app-footer></app-footer>
(If I remove the app-top-nav
and app-footer
, then the behavior does not change, only the URL indeed changes to /home
as well).
app.component.ts:
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { Router, RouterOutlet } from '@angular/router';
import { HttpClientModule } from '@angular/common/http';
import { DatabaseService, EmailService } from 'src/app/services';
import { UnsubscribeGroup } from './interfaces/unsubscribe-group.enum';
import { FilterMatchMode, PrimeNGConfig } from 'primeng/api';
import { TopNavComponent } from "./components/top-nav/top-nav.component";
import { FooterComponent } from "./components/footer/footer.component";
import { CookieHandlerService} from "./services/cookie.service"
@Component({
selector: 'app-root',
standalone: true,
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
imports: [CommonModule, RouterOutlet, HttpClientModule, TopNavComponent, FooterComponent]
})
export class AppComponent {
constructor(private databaseService: DatabaseService, private emailService: EmailService, private cookie: CookieHandlerService, public primengConfig: PrimeNGConfig, private router: Router) {}
async ngOnInit() {
this.primengConfig.ripple = true;
this.primengConfig.zIndex = {
modal: 1100, // dialog, sidebar
overlay: 1000, // dropdown, overlaypanel
menu: 1000, // overlay menus
tooltip: 1100 // tooltip
};
this.primengConfig.filterMatchModeOptions = {
text: [FilterMatchMode.STARTS_WITH, FilterMatchMode.CONTAINS, FilterMatchMode.NOT_CONTAINS, FilterMatchMode.ENDS_WITH, FilterMatchMode.EQUALS, FilterMatchMode.NOT_EQUALS],
numeric: [FilterMatchMode.EQUALS, FilterMatchMode.NOT_EQUALS, FilterMatchMode.LESS_THAN, FilterMatchMode.LESS_THAN_OR_EQUAL_TO, FilterMatchMode.GREATER_THAN, FilterMatchMode.GREATER_THAN_OR_EQUAL_TO],
date: [FilterMatchMode.DATE_IS, FilterMatchMode.DATE_IS_NOT, FilterMatchMode.DATE_BEFORE, FilterMatchMode.DATE_AFTER]
};
this.router.navigate(['/home']);
}
}
Trying to remove the last line: this.router.navigate(['/home']);
has no effect.
main.ts:
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app/app.component';
import { environment } from 'src/environments/environment';
import { enableProdMode, importProvidersFrom } from '@angular/core';
import {
PreloadAllModules,
provideRouter,
withDebugTracing,
withPreloading,
withRouterConfig
}
from '@angular/router';
import { appConfig } from './app/app.config';
if (environment.production) {
enableProdMode();
}
bootstrapApplication(AppComponent, appConfig)
.catch((err) => console.error(err));
app.config:
import { ApplicationConfig, importProvidersFrom } from '@angular/core';
import {
PreloadAllModules,
provideRouter,
withDebugTracing,
withPreloading,
withRouterConfig
}
from '@angular/router';
import { provideHttpClient } from '@angular/common/http';
import { routes } from './app.routes';
export const appConfig: ApplicationConfig = {
providers: [provideRouter(routes), provideHttpClient() ]
};
app.routes:
import { Routes } from '@angular/router';
import { HomeComponent } from './pages/home/home.component';
import { TeamComponent } from './pages/team/team.component';
import { SignupComponent } from './pages/signup/signup.component';
import { TermsComponent } from './pages/terms/terms.component';
import { PrivacyComponent } from './pages/privacy/privacy.component';
export const routes: Routes = [
{ path: 'home', component: HomeComponent },
{ path: 'signup', component: SignupComponent },
{ path: 'team', component: TeamComponent },
{ path: 'terms', component: TermsComponent },
{ path: 'privacy', component: PrivacyComponent },
{ path: '', redirectTo: 'home', pathMatch: 'full' },
{ path: '**', redirectTo: 'home' }
];
index.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>MyDreamTeam</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
</body>
</html>
What am I missing, please?
In my top-nav.component.ts, I was importing this module:
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
Removing this import (from the imports array of the component) - solved the problem!
You can see this in the stackblitz provided above. URL:
https://stackblitz.com/edit/stackblitz-starters-kvfyb5?file=src%2Fmain.ts
https://stackblitz-starters-kvfyb5.stackblitz.io/
Remove the BrowserAnimationsModule import in the top-nav component - and the problem goes away. This works in my local implementation as well now.
In Stackblitz, you can see that the console throws this error if this import exists:
Error: NG05100: Providers from the BrowserModulehave already been loaded. If you need access to common directives such as NgIf and NgFor, import theCommonModule instead.
Problem is, in my local setup, this error is not showing in the console, so I had no idea! So, couple of takeaways: