RSS‑ридер на SvelteKit — простой пошаговый туториал
Создадим минимальный RSS‑ридер на SvelteKit: настроим проект, добавим API‑роут для проверки RSS, сохраним подписки в localStorage и отобразим список записей. Подойдёт для агрегации блогов и новостных лент; в статье есть готовые примеры кода, чек‑листы, варианты расширения и советы по безопасности.

Картинка: ноутбук с запущенным RSS‑ридером Newsboat на экране
Введение
RSS — это простой стандарт для структурированной доставки веб‑контента. Он широко используется для агрегации статей, блогов и подкастов. Написать свой RSS‑ридер несложно, а SvelteKit делает задачу ещё проще за счёт удобной файловой маршрутизации и серверных хуков.
В этой инструкции вы найдёте пошаговую сборку простого клиента на SvelteKit, готовые фрагменты кода и рекомендации по расширению и безопасному использованию.
Важное
- Для работы понадобится Node.js и менеджер пакетов (npm или yarn).
- Код доступен под MIT‑лицензией в примечательной репозитории (в статье предполагается знакомство с базовой структурой).
Что нужно подготовить
Минимальный набор:
- Node.js (14+ или актуальная LTS)
- npm или yarn
- Базовые навыки работы с терминалом и git (опционально)
Если Node ещё не установлен, воспользуйтесь официальным установщиком с nodejs.org.
Создание проекта SvelteKit
Откройте терминал и выполните команду создания проекта:
# с npm
npm create svelte
# или с yarn
yarn create svelteПри запуске CLI от Vite выберите имя проекта и шаблон «Skeleton project». Отключите TypeScript (если хотите чистый JS) и примите остальные опции по необходимости. Затем перейдите в директорию проекта и установите зависимости:
# с npm
npm install
# или с yarn
yarnУстановите две полезные библиотеки: rss‑parser для разбора XML и moment для удобного форматирования дат:
# с npm
npm install rss-parser
npm install moment
# или с yarn
yarn add rss-parser
yarn add momentЗапустите dev‑сервер:
# с npm
npm run dev
# или с yarn
yarn devОчистите содержимое файла App.css и измените структуру проекта так, как показано ниже. Создайте недостающие директории и пустые файлы при необходимости.
Картинка: дерево папок проекта с выделенной папкой src/lib и routes
В проекте вам понадобится изменить только папку src. Она должна содержать:
- lib/
- addToLocalStorage.js
- routes/
- +layout.js
- +layout.svelte
- +page.svelte
- +server.js
- feed/
- [title]/
- +page.server.js
- +page.svelte
- [title]/
Примечание: при создании папки [title] в некоторых shell‑ах квадратные скобки используют для шаблонов. В этом случае создавайте так:
mkdir '[title]'Создание API‑роута проверки RSS
Откройте файл routes/+server.js и импортируйте утилиту json и Parser из rss‑parser:
import { json } from "@sveltejs/kit";
import Parser from "rss-parser";
export async function GET({ url }) {
const rssLink = url.searchParams.get('url');
const parser = new Parser();
let feed;
try {
feed = await parser.parseURL(rssLink);
} catch (e) {
return json({ message: 'Internal Error' }, { status: 500 });
}
return json(feed);
}Пояснение: этот роут получает параметр url, пробует распарсить его как RSS и возвращает JSON. В примере добавлена простая обработка ошибок.
Главная страница (routes/+page.svelte)
В script импортируем утилиту добавления в localStorage и объявляем переменные url и ready:
Разметка формы ввода и проверка feed:
RSS Reader
Добавить новую ленту:
{
if (url.length > 0) {
setTimeout(() => {
ready = true;
}, 250);
} else {
ready = false;
}
}}
/>
{#if ready}
{#await fetch(`/?url=${encodeURIComponent(url)}`).then((res) => res.json())}
Сбор информации... Пожалуйста, подождите
{:then data}
{#if data.message === 'Internal Error'}
Что‑то пошло не так... Проверьте URL и попробуйте снова
{:else}
{#if data.image}
{/if}
{data.title}
{data.description || ''}
{console.log(data) || ''}
{/if}
{/await}
{/if}
Краткое объяснение: когда поле не пустое, вызывается API роут для проверки. Если feed корректен — показываем заголовок, описание и кнопку добавления.
Базовые стили:
Совет: при интеграции с реальным UI используйте debounce вместо setTimeout для лучшей UX.
Настройка layout (routes/+layout.js и +layout.svelte)
В +layout.js укажем, что рендер на сервере отключён (приложение хранит данные в localStorage и должно выполняться на клиенте):
export const prerender = false;
export const ssr = false;В +layout.svelte читаем подписки и показываем навбар:
Примечание: использовано encodeURIComponent для корректной работы ссылок с пробелами и спецсимволами.
Сохранение подписки в localStorage (src/lib/addToLocalStorage.js)
Создайте файл lib/addToLocalStorage.js и добавьте:
export default function addToLocalStorage(title, url) {
let feedInLocalStorage = JSON.parse(localStorage.getItem('feeds')) || [];
localStorage.setItem(
'feeds',
JSON.stringify([...feedInLocalStorage, { title: title, url: url }])
);
}Это простая функция, которая добавляет объект с title и url в массив feeds.
Отрисовка записей конкретной ленты (routes/feed/[title])
В +page.server.js парсим RSS на серверной стороне для этой страницы:
import Parser from 'rss-parser';
export async function load({ url }) {
const rssLink = url.searchParams.get('url');
const parser = new Parser();
let feed = await parser.parseURL(rssLink);
return { ...feed };
}В +page.svelte отобразим элементы и дату через moment:
{#if data.items}
{#each data.items as item}
{@const number = data.items.indexOf(item)}
{number + 1}. {@html item.title}
{item.contentSnippet || ''}
{/each}
{:else}
Что‑то пошло не так...
{/if}
Короткие советы по UX и надёжности
- Сохраняйте только валидированные URL‑ы (как у нас — через API на сервере).
- Добавьте debounce 300–500 мс для поля ввода, чтобы не делать слишком частых запросов.
- Для больших лент применяйте пагинацию или ленивую подгрузку (infinite scroll).
- Кешируйте ответ с сервера (например, в IndexedDB) с TTL, чтобы снизить количество запросов и ускорить загрузку.
Когда этот подход НЕ подойдёт
- Если нужен realtime (push) — RSS не обеспечивает мгновенной доставки новых событий.
- Если контент строго персонализирован и требует аутентификации — стандартный публичный RSS обычно не подходит.
- Для защищённых данных, требующих сложной авторизации, лучше использовать API с OAuth и HTTPS.
Альтернативные подходы
- Использовать сервисы агрегирования (Feedly, Inoreader) и интегрироваться через их API.
- Реализовать сервер‑агрегатор на Node.js с очередями и кэшированием (Redis) для масштабируемых решений.
- WebSub/Callback (ранее PubSubHubbub) для подписки на уведомления об обновлениях (приближает к realtime).
Мини‑методология: как эволюционировать простой ридер в продакшен
- Добавить серверный слой с очередью обновлений (каждую ленту опрашивать по расписанию).
- Хранить результаты в БД (Postgres/Redis) с полями: guid, title, link, isoDate, contentSnippet.
- Убедиться, что обработка дублируется по guid/ссылке, чтобы не показывать повторно.
- Реализовать учетную запись пользователя и синхронизацию подписок.
Безопасность и приватность
- Все запросы к внешним RSS должны идти через сервер (проксирование), чтобы не раскрывать конечные IP/ключи.
- Убедитесь, что внешние HTML в полях title/content безопасны: либо рендерьте как текст, либо применяйте sanitizer при вставке {@html}.
- Для аудита личных подписок храните минимально необходимую информацию и предоставьте кнопку «удалить мои данные».
- Если вы храните персональные данные пользователей — учитывайте требования локального законодательства и GDPR для ЕС.
Критерии приёмки
- Подписка добавляется и сохраняется в localStorage.
- При переходе на страницу ленты (+page.server.js) отображаются элементы feed.items.
- Для некорректного URL отображается понятное сообщение об ошибке.
- Страницы корректно работают в браузерах с отключённым JavaScript (где это релевантно) — в нашем примере SSR отключён, поэтому тестируйте поведение клиента.
Тестовые случаи (примеры)
- Ввести корректный RSS URL — увидеть название и описание, добавить в подписки.
- Ввести некорректный URL — получить сообщение об ошибке.
- Добавить несколько подписок — проверить, что навбар показывает их в обратном порядке.
- Перезагрузить страницу — подписки остаются (localStorage).
Роли и чек‑листы
Разработчик:
- Запустить проект локально
- Прогнать сценарии добавления/удаления подписки
- Настроить простую обработку ошибок
QA:
- Проверить кроссбраузерность
- Проверить поведение при медленном соединении
- Тестировать XSS через поля title/content
Пользователь:
- Добавить RSS из любимого блога
- Перейти к записи и открыть ссылку в новой вкладке
Примеры расширений и миграции
- Добавить авторизацию и хранить подписки на сервере (миграция localStorage → пользовательский профиль).
- Параллельный режим: использовать Service Worker для фоновой синхронизации лент.
- Экспорт/импорт OPML для переноса подписок между сервисами.
Краткий пример runbook на случай сбоя парсера
- Проверить логи сервера — есть ли ошибки network/timeout.
- Попробовать вручную запросить проблемный URL через curl.
- Если сайт отдаёт HTML вместо XML — пометить ленту как некорректную и уведомить пользователя.
- Временно отключить частое опрашивание проблемных лент (backoff).
Картинка: скриншот интерфейса простого RSS‑проекта
Что такое RSS и где он полезен
RSS удобен, когда вы хотите агрегировать статьи с нескольких сайтов в одном интерфейсе. Это экономит время, уменьшает необходимость посещать много источников вручную и позволяет выстроить собственную информационную панель.
Когда не использовать RSS
- Если нужна двусторонняя интерактивность (комментарии в реальном времени, чат).
- Если данные требуются защищённо и индивидуально (например, банковские оповещения).
Заключение
Вы только что создали простой RSS‑ридер на SvelteKit, изучили ключевые файлы и узнали, как хранить подписки в localStorage. Для продакшен‑решения рекомендуем добавить аутентификацию, серверное кеширование и защиту от XSS.
Короткое объявление (100–200 слов)
Создайте свой RSS‑ридер на SvelteKit за один вечер. В руководстве — пошаговая установка проекта, проверка валидности RSS, сохранение подписок в localStorage и отображение последних записей. Включены примеры кода, советы по UX, чек‑листы для разработчика и тесты. Это хорошая отправная точка для тех, кто хочет агрегировать контент без сторонних сервисов.
Социальная превью‑заготовка
OG title: RSS‑ридер на SvelteKit — быстро и просто OG description: Пошаговый туториал: настройка проекта, проверка RSS, сохранение подписок и отображение записей. Готовые фрагменты кода и советы по безопасности.
Подсумок
- Простая архитектура: клиент (SvelteKit) + rss‑parser + момент
- Хранение подписок в localStorage для быстрого старта
- Набор практических улучшений для развёртывания в продакшен
Похожие материалы
Добавить второе лицо в Face ID — инструкция
Простой калькулятор на HTML/CSS/JavaScript
Как удалить аккаунт пользователя на PS4
Сброс сетевых настроек в Windows 10 — быстро и безопасно
Наследование в OOP: понятие, примеры и лучшие практики