Гид по технологиям

RSS‑ридер на SvelteKit — простой пошаговый туториал

7 min read Веб Обновлено 29 Dec 2025
RSS‑ридер на SvelteKit — простой туториал
RSS‑ридер на SvelteKit — простой туториал

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

newsboat rss feed reader for linux running on a laptop

Картинка: ноутбук с запущенным 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 и измените структуру проекта так, как показано ниже. Создайте недостающие директории и пустые файлы при необходимости.

A screenshot of the project directory represented as a tree

Картинка: дерево папок проекта с выделенной папкой src/lib и routes

В проекте вам понадобится изменить только папку src. Она должна содержать:

  • lib/
    • addToLocalStorage.js
  • routes/
    • +layout.js
    • +layout.svelte
    • +page.svelte
    • +server.js
    • feed/
      • [title]/
        • +page.server.js
        • +page.svelte

Примечание: при создании папки [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} {data.title} {/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).

Мини‑методология: как эволюционировать простой ридер в продакшен

  1. Добавить серверный слой с очередью обновлений (каждую ленту опрашивать по расписанию).
  2. Хранить результаты в БД (Postgres/Redis) с полями: guid, title, link, isoDate, contentSnippet.
  3. Убедиться, что обработка дублируется по guid/ссылке, чтобы не показывать повторно.
  4. Реализовать учетную запись пользователя и синхронизацию подписок.

Безопасность и приватность

  • Все запросы к внешним 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 на случай сбоя парсера

  1. Проверить логи сервера — есть ли ошибки network/timeout.
  2. Попробовать вручную запросить проблемный URL через curl.
  3. Если сайт отдаёт HTML вместо XML — пометить ленту как некорректную и уведомить пользователя.
  4. Временно отключить частое опрашивание проблемных лент (backoff).

Screenshot of the RSS Project

Картинка: скриншот интерфейса простого 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 для быстрого старта
  • Набор практических улучшений для развёртывания в продакшен
Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Добавить второе лицо в Face ID — инструкция
iPhone

Добавить второе лицо в Face ID — инструкция

Простой калькулятор на HTML/CSS/JavaScript
Frontend

Простой калькулятор на HTML/CSS/JavaScript

Как удалить аккаунт пользователя на PS4
Гайды

Как удалить аккаунт пользователя на PS4

Сброс сетевых настроек в Windows 10 — быстро и безопасно
Windows

Сброс сетевых настроек в Windows 10 — быстро и безопасно

Наследование в OOP: понятие, примеры и лучшие практики
Программирование

Наследование в OOP: понятие, примеры и лучшие практики

Быстрая перекраска шаблона в Canva
Дизайн

Быстрая перекраска шаблона в Canva