router-outlet is not a known element shows up when Angular can’t see the Router features in the place you used
You add a route, drop a
You’ll get quick checks, step-by-step fixes, and a reusable checklist for NgModule apps, standalone apps, lazy loading, tests, and libraries.
Why This Error Shows Up
Angular validates templates at build time. When it sees a tag it doesn’t recognize as HTML, it tries to match it to a component or directive that’s available to the current compilation context. If that context doesn’t include the Router bits that declare
That “current context” is the part that trips people up. In Angular, what a template can use depends on where that template is declared, and what that declared thing imports. If your template belongs to a component that never imports routing,
What Angular Is Looking For
The Router exposes
Quick Signals That Point To The Root Cause
- Error shows in AppComponent — Your root setup is missing RouterModule (NgModule) or RouterOutlet + provideRouter (standalone).
- Error shows in a feature layout — The feature module or standalone component doesn’t import routing bits.
- Error shows only in tests — TestBed isn’t importing RouterTestingModule or RouterModule, so the template compiles without routing.
Router-Outlet Is Not A Known Element In Angular Apps
If you’re seeing “router-outlet is not a known element” in your build output, start by identifying which file owns the template that contains
Next, check your project style. Angular projects created in recent years often use standalone components by default, while many existing apps still use NgModules. The fix is different in each style, so it helps to confirm what you’re working with before you change anything.
How To Tell Which Style You Have
- Look for “standalone: true” — If your component decorator includes it, the component owns its own imports.
- Look for app.module.ts — If you have a root module with declarations/imports, you’re in NgModule land.
- Look at main.ts — If it uses bootstrapApplication, it’s standalone bootstrapping. If it uses platformBrowserDynamic().bootstrapModule, it’s NgModule bootstrapping.
Fixing Router Outlet Not A Known Element Error Step By Step
This section walks through the fixes in the order that saves the most time. Start with the style that matches your app, apply the steps, then rebuild. During migration, keep one pattern per feature.
Fix In A Classic NgModule App
In NgModule apps, the rule is simple. The module that declares the component using
- Open The Declaring Module — Find the module that lists your component in
declarations. - Import RouterModule — Add RouterModule to the module’s
importsarray. - Export RouterModule When Sharing — If you use a routing module, export RouterModule from it.
- Rebuild From A Clean State — Stop the dev server and run it again so the compiler resets.
// app.module.ts (or the feature module that declares the layout)
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
@NgModule({
imports: [
RouterModule
]
})
export class AppModule {}
Fix In A Standalone App
Standalone apps shift the import responsibility to the component. You can make
- Import RouterOutlet In The Layout Component — Add it to the component’s
importsarray. - Confirm Routes Are Provided — In your bootstrap file, provideRouter(routes) must run once.
- Restart The Dev Server — A restart catches stale build state after routing changes.
// app.component.ts (standalone)
import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
@Component({
selector: 'app-root',
standalone: true,
imports: [RouterOutlet],
template: ' '
})
export class AppComponent {}
// main.ts (standalone bootstrap)
import { bootstrapApplication } from '@angular/platform-browser';
import { provideRouter } from '@angular/router';
import { routes } from './app/app.routes';
import { AppComponent } from './app/app.component';
bootstrapApplication(AppComponent, {
providers: [provideRouter(routes)]
});
Fix When Routing Lives In A Separate File
Some apps keep routes in a dedicated file and import them into a routing module or into main.ts. That’s fine. The thing to verify is that the file actually exports a routes array and that it matches the type Angular expects. A broken export can send you chasing the wrong file.
- Check The Export Name — If main.ts imports
routes, the routes file must exportroutes. - Check The Type — Use
Routesfrom@angular/routerso the compiler catches typos early. - Keep The File Pure — Avoid side effects in the routes file; keep it as a plain export.
Common Places People Miss The Import
Once routing is set up once, you can still hit this error later when you add a new layout, create a feature area, or move templates around. These are the spots where the import gap shows up most often.
Feature Modules With Their Own Layout
If a feature module declares a layout component that includes
- Import RouterModule In The Feature Module — Put it next to CommonModule in the feature module imports.
- Use RouterModule.forChild For Routes — Keep route config scoped to the feature module.
- Keep The Layout In The Same Feature — Moving the layout into a shared module changes where it must be imported.
Standalone Feature Components
Standalone components don’t inherit imports from a parent component. Each standalone component needs its own imports list. If a feature layout is standalone and uses
Unit Tests And Shallow Renders
Tests compile templates too. If you render a component that contains
- Add RouterTestingModule — Import it in TestBed imports for the spec file.
- Stub Routes If Needed — Provide a tiny route list when the component expects navigation.
- Watch For Standalone Specs — In standalone tests, also add RouterOutlet in component imports when you compile the component directly.
Table Of Causes And Fast Fixes
Use this table to match the error to the file you’re working in.
| Where It Fails | Most Likely Cause | Fix To Try |
|---|---|---|
| AppComponent template | Router not set up at root | Import RouterOutlet (standalone) or RouterModule (NgModule), then provide routes |
| Feature layout template | Routing not imported in that feature | Import RouterModule in the feature module, or import RouterOutlet in the standalone layout |
| Only during tests | TestBed missing router setup | Import RouterTestingModule, then compile again |
| After moving components | Template now belongs to a different module | Fix imports in the new declaring module or standalone component |
| Library component | Library module not exporting RouterModule | Export RouterModule from the library module, or document RouterOutlet import for standalone use |
Edge Cases That Waste Time If You Miss Them
If the standard fixes don’t clear it, one of these edge cases is often the reason.
Typos And Wrong Tag Names
Angular treats
- Use The Exact Tag — Write
in templates. - Avoid Uppercase — Keep it lowercase; Angular selectors are case-sensitive in practice.
- Check Copy-Paste Artifacts — Hidden characters from editors can break tags.
Mixing Standalone And NgModules Mid-Feature
Angular allows interop, yet it’s easy to end up with a layout declared in a module, a child route declared in a standalone file, and a test that compiles only one side. When things get tangled, fix the ownership first: decide whether the layout is module-based or standalone, then align the imports with that choice.
- Pick One Owner For The Layout — Either keep it in a module or mark it standalone.
- Align Routes With The Owner — Use RouterModule.forChild in module features, or child route arrays in standalone features.
- Re-run The Build Clean — Delete the output folder if your setup keeps stale artifacts.
Using RouterOutlet Inside A Library
If you publish a library component that contains
Template Compilation In A Different Build Target
Sometimes the app build passes, then a separate target fails: server rendering or a test runner. Trace which entry file that target uses and confirm routing setup there too.
A Clean Checklist You Can Keep And Reuse
Once you fix this once, you’ll want a repeatable way to avoid it on the next app. Use this checklist when you add routing, add a new layout, or migrate between module-based and standalone styles.
- Find The Template Owner — Start with the component named in the error, not a random shared file.
- Match The App Style — NgModule components rely on module imports; standalone components rely on component imports.
- Import The Right Router Piece — RouterModule for modules, RouterOutlet for standalone templates.
- Provide Routes Once At Bootstrap — Standalone apps need provideRouter(routes) in the bootstrap config.
- Scope Feature Routes Properly — Use forChild in module features, and child route arrays in standalone features.
- Fix Tests Alongside App Code — Add RouterTestingModule or RouterOutlet so the spec compiles templates the same way.
- Restart After Large Routing Changes — A full restart catches stale compiler state and clears false negatives.
If you’re stuck, search your project for RouterOutlet and RouterModule then follow the import chain to the template.
If you hit this error again, the fastest path is to repeat two questions: where is
Want official reference pages? These two links show the directive itself and routing with outlets: RouterOutlet API and Routing With Outlets.
