Astro отлично подходит для создания как статических, так и серверных сайтов, но одна вещь, которая сдерживает его потенциал SSR, — это невозможность вернуть страницу 404 без простого перенаправления на страницу 404 (например, /404
). Однако мы можем воспользоваться возможностью вернуть наш собственный объект Response
, чтобы вернуть нашу страницу 404.
Проблема
Допустим, у меня есть базовый сайт Astro с 3 страницами.
index.astro
- Главная страница[id].astro
— динамическая страница, возвращающая контент из CMS404.astro
- Страница 404
Я хочу иметь возможность возвращать страницу 404, когда пользователь посещает несуществующую страницу. Например, если я посещаю /does-not-exist
, я хочу иметь возможность вернуться на страницу 404. Поэтому я возвращаю перенаправление из моего скрипта компонента, если запрошенный контент не существует.
--- const { id } = Astro.params; const page = await getPage(id); if (!page) return Astro.redirect('/404') --- {page}
Это прекрасно работает, но это не идеальное решение. Итак, теперь давайте попробуем вернуть пользовательский ответ.
Решение
Мы можем выполнить fetch
запрос к нашей странице 404 и вернуть ответ, используя содержимое этой страницы.
--- const { id } = Astro.params; const page = await getPage(id); if (!page) { const error = await fetch(`${Astro.url}/404`) return new Response(error.body, { headers: error.headers, status: 404, statusText: 'Not Found' }) } --- {page}
Это немного многословно, поэтому давайте извлечем его во вспомогательную функцию, которую мы сможем использовать на разных страницах. И пока мы это делаем, давайте сделаем его немного более гибким.
export async function status(status: number, url: string) { const res = await fetch(url) return new Response(res.body, { headers: res.headers, status, }) }
Теперь мы можем использовать его так:
--- import { status } from '../lib/status.ts' const { id } = Astro.params; const page = await getPage(id); if (!page) return status(404, `${Astro.url}/404`) --- {page}
Заключение
Это довольно простое решение, но немного многословное. Будем надеяться, что в будущем Astro добавит метод Astro.status
или что-то в этом роде, но пока это довольно хороший обходной путь.
Дополнительные материалы на PlainEnglish.io.
Подпишитесь на нашу бесплатную еженедельную рассылку новостей. Подпишитесь на нас в Twitter, LinkedIn, YouTube и Discord .
Заинтересованы в масштабировании запуска вашего программного обеспечения? Ознакомьтесь с разделом Схема.