21

Basically, how to do the ff. in SvelteKit:

  • Add a custom 404 page first.
  • Have a different generic Error page that will show a message/description about the error in SvelteKit
Zedd
  • 2,069
  • 2
  • 15
  • 35
  • You can also start by copying the default sveltekit error page `node_modules/@sveltejs/kit/assets/components/error.svelte` to `src/layouts/__error.svelte` and then customize it. – Quinn Comendant Jun 12 '22 at 19:05

2 Answers2

34

After reading through the updated docs, I found this:

Updated solution:

If an error occurs during load, SvelteKit will render a default error page. You can customise this error page on a per-route basis by adding an +error.svelte file:

src/routes/blog/[slug]/+error.svelte

<script>
  import { page } from '$app/stores';
</script>

<h1>{$page.status}: {$page.error.message}</h1>

SvelteKit will 'walk up the tree' looking for the closest error boundary — if the file above didn't exist it would try src/routes/blog/+error.svelte and src/routes/+error.svelte before rendering the default error page.

Of course, this is your own error page component so you may modify it however you want. I've put a GIF on mine, by the way, so that it would be nice-looking even though it's an error page, hoping that the users won't get that much irritated when they get an error on my site ;)

Outdated solution:

If you have the following in your code, please update it to the updated solution found in the docs (as shown above).

  1. Create an __error.svelte file in your routes folder.
  2. Inside that file, you can do this as shown in the docs:
<script context="module">
  export function load({ error, status }) {
      return {
          props: {
              title: `${status}: ${error.message}`
          }
      };
  }
</script>

<script>
  export let title;
</script>

<h1>{title}</h1>
  1. We're not done yet! You can check for the status code and then render different screen components. (You can configure the props inside the load function, by the way):
<script context="module">
  export function load({ error, status }) {
      return {
          props: {
              message: error.message,
              status // same as status: status
          }
      };
  }
</script>

<script>
  import ErrorScreen from '../components/screens/ErrorScreen.svelte'; // your own Error screen component
  import NotFoundScreen from '../components/screens/NotFoundScreen.svelte'; // your own 404 screen component

  export let message;
  export let status;
</script>

{#if status == 404} <!-- Used '==' instead of '===' to match string/number status code (just to be sure) -->
  <NotFoundScreen />
{:else}
  <ErrorScreen {message} {status} />
{/if}
  1. You're all set! You can test it out by changing the #if status == 404 to like #if status == 500 to see if everything works. (Don't forget to change it back to 404).
Zedd
  • 2,069
  • 2
  • 15
  • 35
  • You need to include status in ErrorScreen also, otherwise: Property 'status' is missing in type '{ message: any; }' but required in type '{ message: any; status: any; }' – Bitfinicon Jan 14 '22 at 13:11
  • Is there a way to print the entire trace? For example, on which line number/file the error occurs, etc? – riddle_me_this Feb 12 '22 at 15:35
  • 1
    @vphilipnyc yes, that's possible. "error" (in the load function) has a property named "stack". So when you add it to the "prop" object, you can use it in your template. – Christian Apr 19 '22 at 21:26
4

December 2022 solution

as per docs: https://kit.svelte.dev/docs/advanced-routing#rest-parameters-404-pages

create: src/routes/[...path]/+page.js containing:

import { error } from '@sveltejs/kit';

export function load() {
    throw error(404, '/not-found whatever you want');
}

also create: src/routes/[...path]/+error.svelte containing (for example):

<script>
    import { page } from '$app/stores';
</script>

<div>
    <h1>It seems there has been an error, sorry about that.</h1>
    {#if $page?.error}
        <div class="mt-4 p-4 border-y-2">
            {#if $page?.status}
                <p>Page status: {$page?.status}</p>
            {/if}
            {#if $page?.error?.message}
                <p>Error message: {$page?.error?.message}</p>
            {/if}
        </div>
    {/if}
</div>

btw, maybe you have some style in layouts, maybe even layout groups so be sure to put a layout file in the same dir to apply them, e.g.:

src/routes/[...path]/+layout.svelte