Reputation: 123
I am using Ionic 4 and Stenciljs for a progressive web app (PWA) and I am not also using Angular. I am using ion-router for the routing. Can anybody help me understand how to implement a fallback "Page Not Found" page to display when someone enters a URL for which there is no defined route (i.e. a page that does not exist)? All the examples I can find assume the use of Angular, but I'm trying to see if I get where I need with just standard web components and no additional framework.
Following is how some of my current router code looks (it makes use of the tabs component).
return (
<ion-router useHash={false}>
<ion-route-redirect from="/" to='/blog' />
<ion-route component="page-tabs">
<ion-route url="/blog" component="tab-blog">
<ion-route component="page-blog"></ion-route>
</ion-route>
<ion-route url="/books" component="tab-books">
<ion-route component="page-books"></ion-route>
</ion-route>
<ion-route url="/art" component="tab-art">
<ion-route component="page-art"></ion-route>
</ion-route>
<ion-route url="/about" component="tab-about">
<ion-route component="page-about"></ion-route>
</ion-route>
<ion-route url="/beaver-cage-command-chron" component="tab-books">
<ion-route component="page-cmd-chron-beaver-cage"></ion-route>
</ion-route>
<ion-route url="/cage" component="tab-books">
<ion-route component="page-cage"></ion-route>
</ion-route>
<ion-route url="/d-1-3-weapons-platoon" component="tab-books">
<ion-route component="page-photos-weapons-platoon"></ion-route>
</ion-route>
<ion-route url="/ray-kelley-silver-star" component="tab-books">
<ion-route component="page-ray-kelley-silver-star"></ion-route>
</ion-route>
<ion-route url="/photos" component="tab-books">
<ion-route url="/:name" component="app-photos"></ion-route>
</ion-route>
<ion-route url="/vietnam-1967-amphibious-combat" component="tab-books">
<ion-route component="page-vietnam-1967-amphibious-combat"></ion-route>
</ion-route>
{blogPostRoutes}
</ion-route>
</ion-router>
);
}
Upvotes: 1
Views: 2549
Reputation: 1
There's a better solution now - using a dynamic route to catch anything that doesn't match an existing route.
<ion-route url=":any" component="page-404" />
If you have protected routes or conditionally rendered routes you can also add that route behind a check like this.
{authLoaded && <ion-route url=":any" component="page-404" />}
Found this answer here: https://github.com/ionic-team/ionic-framework/issues/18687#issuecomment-781214605
Works for vanilla JS / StencilJS
Upvotes: 0
Reputation: 4968
The only way I know of that this is possible is using multiple route redirects:
<ion-router>
<ion-route url="/one" component="page-one" />
<ion-route url="/two" component="page-two" />
<ion-route url="/three" component="page-three" />
<ion-route url="/404" component="page-404" />
<ion-route-redirect from="/one" to="/one" />
<ion-route-redirect from="/two" to="/two" />
<ion-route-redirect from="/three" to="/three" />
<ion-route-redirect from="*" to="/404" />
</ion-router>
That is because only the first matching route-redirect will be called. However this becomes quite unfeasible for a large number of routes. A feature request for adding a fallback route is being tracked on Ionic's Github Repo.
Edit: I actually just had the idea of wrapping this in a functional component to avoid having so much duplication:
import { FunctionalComponent } from '@stencil/core';
import { JSX } from '@ionic/core';
export const Route: FunctionalComponent<JSX.IonRoute> = props => [
<ion-route {...props} />,
<ion-route-redirect from={props.url} to={props.url} />,
];
import { Route } from './route';
<ion-router>
<Route url="/one" component="page-one" />
<Route url="/two" component="page-two" />
<Route url="/three" component="page-three" />
<ion-route-redirect from="*" to="/404" />
</ion-router>
Upvotes: 2
Reputation: 336
You can add a route for fallback page at the end of the router like so
const routes: Route = [
{path: "OtherPaths",component: OtherPathsComponent},
{path: "PathNotFound", component: PathNotFoundComponent},
{path: "**", redirectTo: "PathNotFound"}
]
Upvotes: 1