Bird
Raised Fist0
Svelteframework~30 mins

Hooks (handle, handleError, handleFetch) in Svelte - Mini Project: Build & Apply

Choose your learning style10 modes available
Using SvelteKit Hooks: handle, handleError, and handleFetch
📖 Scenario: You are building a simple SvelteKit app that fetches user data from an API. You want to add hooks to manage requests, handle errors gracefully, and modify fetch calls globally.
🎯 Goal: Build a SvelteKit hooks.server.js file that implements handle to log requests, handleError to catch and log errors, and handleFetch to add a custom header to all fetch requests.
📋 What You'll Learn
Create a handle hook that logs the request method and URL
Add a handleError hook that logs errors and returns a custom message
Implement a handleFetch hook that adds a X-Custom-Header to all fetch requests
💡 Why This Matters
🌍 Real World
Hooks in SvelteKit let you control how requests and errors are handled globally, which is useful for logging, authentication, and modifying fetch calls in real apps.
💼 Career
Understanding hooks is important for building robust SvelteKit applications that handle errors and requests cleanly, a common requirement in professional web development.
Progress0 / 4 steps
1
Create the handle hook to log requests
Create a handle function in hooks.server.js that takes { event, resolve } as parameters. Inside, log the request method and URL using console.log. Then return the result of calling resolve(event).
Svelte
Hint

Use console.log to print the request method and URL from event.request.method and event.url.

2
Add the handleError hook to log errors
Add an async handleError function in hooks.server.js that takes { error, event } as parameters. Inside, log the error message with console.error. Return an object with message set to 'An unexpected error occurred'.
Svelte
Hint

Use console.error to log the error message from error.message. Return an object with a friendly message.

3
Implement the handleFetch hook to add a custom header
Add an async handleFetch function in hooks.server.js that takes { request, fetch } as parameters. Clone the request and add a header X-Custom-Header with value MyHeaderValue. Use the modified request with fetch and return the response.
Svelte
Hint

Create a new Request object copying the original, then add the header with headers.set.

4
Complete the hooks.server.js with all hooks combined
Ensure your hooks.server.js file exports all three hooks: handle, handleError, and handleFetch with the exact implementations from previous steps.
Svelte
Hint

Make sure all three functions are exported and present in the file.

Practice

(1/5)
1. What is the main purpose of the handle hook in SvelteKit?
easy
A. To catch and handle errors during server-side rendering
B. To define client-side event handlers for UI elements
C. To intercept and modify fetch requests made by the app
D. To manage and modify incoming requests and outgoing responses

Solution

  1. Step 1: Understand the role of handle hook

    The handle hook runs on every request and can modify the request or response.
  2. Step 2: Compare with other hooks

    handleError is for errors, handleFetch is for fetch interception, so they don't manage requests/responses directly.
  3. Final Answer:

    To manage and modify incoming requests and outgoing responses -> Option D
  4. Quick Check:

    handle = manage requests/responses [OK]
Hint: Remember: handle = request/response management [OK]
Common Mistakes:
  • Confusing handle with handleError
  • Thinking handleFetch manages requests directly
  • Assuming handle is for client-side events
2. Which of the following is the correct syntax to define a handleError hook in hooks.server.js?
easy
A. export function handleError({ request, response }) { return response; }
B. export async function handleError(event) { console.error(event.error); }
C. export function handleError({ error, event }) { return { message: error.message }; }
D. export function handleError({ fetch, event }) { return fetch(event); }

Solution

  1. Step 1: Recall handleError parameters

    The handleError hook receives an object with error and event.
  2. Step 2: Check syntax correctness

    export function handleError({ error, event }) { return { message: error.message }; } correctly destructures { error, event } and returns an object with a message.
  3. Final Answer:

    export function handleError({ error, event }) { return { message: error.message }; } -> Option C
  4. Quick Check:

    handleError({ error, event }) correct syntax [OK]
Hint: handleError gets { error, event } object [OK]
Common Mistakes:
  • Using wrong parameters like request or fetch
  • Not destructuring the error object
  • Returning response instead of error info
3. Given this handleFetch hook, what will be logged when the app fetches /api/data?
export async function handleFetch({ request, fetch }) {
  console.log('Fetching:', request.url);
  const response = await fetch(request);
  return response;
}
medium
A. Fetching: http://localhost/api/data
B. Fetching: /api/data
C. Fetching: undefined
D. No output logged

Solution

  1. Step 1: Understand handleFetch parameters

    The request object has a full URL in its url property.
  2. Step 2: Analyze the console.log statement

    The code logs 'Fetching:' plus the full request.url, which includes the origin like 'http://localhost/api/data'.
  3. Final Answer:

    Fetching: http://localhost/api/data -> Option A
  4. Quick Check:

    request.url logs full URL [OK]
Hint: request.url in handleFetch is full URL [OK]
Common Mistakes:
  • Expecting only path instead of full URL
  • Thinking request.url is undefined
  • Assuming no console output
4. Identify the error in this handle hook code snippet:
export async function handle({ event, resolve }) {
  const response = await resolve(event);
  response.headers.set('X-Custom', 'value');
  return response;
}
medium
A. Cannot modify headers on the response object directly; it is immutable
B. Missing await before resolve(event)
C. Incorrect parameter names; should be { request, resolve }
D. handle hook must be synchronous, not async

Solution

  1. Step 1: Check response header modification

    The response object is immutable; headers cannot be set directly on it.
  2. Step 2: Confirm other parts are correct

    Await is used correctly, parameter names are valid, and handle can be async.
  3. Final Answer:

    Cannot modify headers on the response object directly; it is immutable -> Option A
  4. Quick Check:

    Response headers are immutable [OK]
Hint: Response headers are immutable; clone before modifying [OK]
Common Mistakes:
  • Trying to set headers directly on response
  • Confusing parameter names
  • Thinking handle must be synchronous
5. You want to add a custom header X-User with the username from event.locals.user to every fetch request made by your app. Which handleFetch hook implementation correctly achieves this?
hard
A. export async function handleFetch({ request, fetch }) { request.headers.set('X-User', event.locals.user); return fetch(request); }
B. export async function handleFetch({ request, fetch, event }) { const modifiedRequest = new Request(request, { headers: { ...Object.fromEntries(request.headers), 'X-User': event.locals.user } }); return fetch(modifiedRequest); }
C. export async function handleFetch({ request, fetch, event }) { request.headers.append('X-User', event.locals.user); return fetch(request); }
D. export async function handleFetch({ request, fetch, event }) { const headers = new Headers(request.headers); headers.set('X-User', event.locals.user); const modifiedRequest = new Request(request.url, { method: request.method, headers }); return fetch(modifiedRequest); }

Solution

  1. Step 1: Understand immutability of request headers

    Request headers are immutable; to modify them, create a new Request with new headers while preserving other properties like body.
  2. Step 2: Analyze the correct implementation

    The code that uses new Request(request, { headers: { ...Object.fromEntries(request.headers), 'X-User': event.locals.user } }) clones the original request fully (including body, method, etc.) and overrides the headers correctly.
  3. Step 3: Identify errors in other options

    Directly modifying request.headers with set or append fails because headers are immutable. Creating a new Request with only url, method, and headers omits the body and other request properties.
  4. Final Answer:

    export async function handleFetch({ request, fetch, event }) { const modifiedRequest = new Request(request, { headers: { ...Object.fromEntries(request.headers), 'X-User': event.locals.user } }); return fetch(modifiedRequest); } -> Option B
  5. Quick Check:

    new Request(request, { headers: ... }) clones fully [OK]
Hint: Clone request with new Request(request, { headers: updated }) [OK]
Common Mistakes:
  • Modifying headers directly on original request
  • Not cloning request before changing headers
  • Omitting request body when recreating Request
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard