Skip to content

docs: improve docs around cache control order and redirects #7744

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions packages/docs/src/routes/docs/(qwikcity)/caching/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,6 @@ export default component$(() => {

With the above setup, you will not only have better performance (pages are always served instantly from cache), but you can also have significantly decreased hosting costs, as our server or edge functions only need to run at most once every 5 seconds per page.

## `cacheControl`

Any method that takes a [request event](https://qwik.dev/docs/advanced/request-handling/#request-event) can call `request.cacheControl` to set the cache control headers for the response:

```tsx title="src/routes/layout.tsx"
import type { RequestHandler } from "@builder.io/qwik-city";

Expand Down Expand Up @@ -83,6 +79,22 @@ export const onGet: RequestHandler = async ({ cacheControl }) => {

You can see the full [API reference](https://qwik.dev/api/qwik-city-middleware-request-handler/) of options you can pass to `request.cacheControl`.

## `cacheControl` Order

Any method that takes a [request event](https://qwik.dev/docs/advanced/request-handling/#request-event) can call `request.cacheControl` to set the cache control headers for the response.

Qwik City executes request handlers in a specific order. This is important because if multiple handlers set the cache control policy, **the last one to execute wins**.

The execution order is as follows:

1. **Middleware (`src/middleware/index.ts`)**
2. **Layouts (from the root layout downwards)**
3. **Page endpoints (`src/routes/..../index.tsx`)**

This means that the cache control set in a page's `onGet` handler will override any cache control set in a layout or middleware. For example, you can set a default cache policy in a root layout, and then override it in a specific page.

When using `redirect()`, there is a special case for caching. See [redirects and caching](/docs/(qwikcity)/guides/redirects/#caching) for more information.

## When not to cache

Caching is generally beneficial, but not right for every page all the time. If your site has URLs that will show different content to different people — for example, pages exclusive to logged-in users or pages that show content based on a user's location — you should avoid using cache-control headers to cache these pages. Instead, render the content of these pages on the server side on a per-visitor basis.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,23 @@ If you do not provide a status code, Qwik City will default to a `302` Found sta

Read more about redirect status codes [here](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#redirection_messages).

## Caching

When you issue a redirect using the `redirect()` method from the `RequestEvent`, Qwik City applies a default cache control policy if one hasn't been explicitly set. This includes `Cache-Control` headers set in a higher-level layout or middleware. For more details on the order of execution, see the [caching documentation](/docs/caching/).

If the redirect's status code is greater than `301` (e.g., `302`, `307`), and you haven't called `cacheControl()` for that request, the `Cache-Control` header will automatically be set to `'no-store'`. This prevents the redirect from being cached by the browser or intermediate caches.

```typescript
export const onGet: RequestHandler = ({ redirect, cacheControl }) => {
// This will result in a `Cache-Control: no-store` header except if cacheControl was called in a middleware or layout above.
throw redirect(302, '/new-location');

// To override the default, set it explicitly
cacheControl('day');
throw redirect(302, '/new-location');
};
```

## Managing multiple redirects

In some cases, you may need to manage multiple redirects based on different conditions. For example, you might want to redirect users from old URLs to new URLs after a site restructure. Additionally, you may want editors in a CMS to manage these redirects as well. Here's one of the ways you can handle multiple redirects in Qwik:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,8 @@ export const onGet: RequestHandler = async ({ status, getWritableStream }) => {

Redirect to a new URL. Notice the importance of throwing to prevent other middleware functions from running. The `redirect()` method will automatically set the `Location` header to the redirect URL.

> **Note**: When using `redirect()`, Qwik City applies a default `Cache-Control` header of `no-store` for redirects with a status code greater than 301. You can learn more about this behavior in the [redirects guide](/docs/guides/redirects/#caching).

<CodeSandbox src="/src/routes/demo/qwikcity/middleware/redirect/index.tsx">
```tsx
import { type RequestHandler } from '@builder.io/qwik-city';
Expand Down
Loading