meez
meez

Reputation: 4788

Astro dynamic routing (SSR mode) and 404 page

I am using Astro and Apollo client to fetch data using GraphQL.

In Astro I am using SSR only.

I have set up the following Astro dynamic routing (SSR mode):

// [...slug].astro

---
import Page from '../components/page/Page.astro';
import Layout from '../layouts/Layout.astro';
---

<Layout title="Test">
  <Page />
</Layout>

And Page.astro:

// Page.astro
---
import PageOne from '../PageOne.astro';
import PageTwo from '../PageTwo.astro';

const uri = `/${Astro.params.uri}`;

const { data, loading } = await client.query<
  GetPageQuery,
  GetPageQueryVariables
>({
  query: GET_PAGE,
  variables: {
    url: uri,
  },
});

const Map = {
  "PageOne": PageOne,
  "PageTwo": PageTwo,
};


const Component = Map[data.page?.type];
---

{loading && <p>Loading...</p>}
{!loading && <Component uri={uri} />}

This is all working fine. So when I request a request an existing route/path uri (which exist in the backend), I can query the type (data.page?.type) and then I map to the proper Astro component, e.g PageOne or PageOne (.astro). However when I navigate to a non-existing url I get an error:

Unable to render Component because it is undefined! Did you forget to import the component or is it possible there is a typo?

How to fix this issue?

Upvotes: 2

Views: 4679

Answers (4)

Carlos Dub&#243;n
Carlos Dub&#243;n

Reputation: 72

The correct way of doing it according to the docs is

---
if(notFound) {
   return Astro.rewrite("/404");
}
---

Upvotes: 0

Robin Millette
Robin Millette

Reputation: 174

Instead of redirecting to a /404/ page, I prefer to keep the URL intact and

return new Response(null, { status: 404 }

Upvotes: 3

Gustavo Bremm
Gustavo Bremm

Reputation: 11

It's actually very simple, but not well documented. Just change the astro response status to 404.

---
// [...slug].astro
if (idNotFound) { // your condition
  Astro.response.status = 404;
  Astro.response.statusText = "Not found";
}
---

<div>This content won't display if the ID is not found</div>

To customize the 404 page, just create a /pages/404.astro file, if you don't have one already.

Upvotes: 1

Alex
Alex

Reputation: 353

You could just add a check if the component is valid and then redirect (or do something else) e.g.

const Component = Map[data.page?.type];

if (!Component) {
  return Astro.redirect("/404");
}

Upvotes: 0

Related Questions