Сегодня мы с вами научимся создавать приложение на Next.js для фильтрации новостей («Мои новости»). Next.js — это современный фреймворк для React, который упрощает разработку веб-приложений благодаря встроенной поддержке серверного рендеринга и статической генерации, оптимизирует производительность и SEO (страница генерируется на сервере и отправляется пользователю в готовом виде, в том числе, например, с уже заполненными данными из базы данных. Это означает, что поисковые системы могут легко индексировать страницу, а пользователи видят контент быстрее).
Нам потребуется около 5 минут для разбора кода и еще 5 минут — для развертывания приложения на сервисе Timeweb Cloud Apps, после чего мы получим:
Вот так будет выглядеть ваше приложение.
Правда, неплохо? А теперь давайте сделаем ваш личный вариант поиска новостей, который вы сможете регулировать и настраивать самостоятельно.
Итак, приступим…
В данной инструкции мы рассмотрим деплой приложения с использованием Github. Мы подготовили для вас готовое приложение (фильтр новостей) для демонстрации простоты деплоя Next.js-приложений на наш сервис Timeweb Cloud Apps. Итак, приступим.
Откройте в браузере страницу репозитория с шаблоном нашего подготовленного приложения и нажмите кнопку «Fork», чтобы скопировать его в свой аккаунт Github.
Сохраните репозиторий в своем аккаунте. Название репозитория можете оставить таким же.
Для автоматического развертывания статических приложений, созданных с использованием Next.js, Svelte, Vue и других фреймворков, компания Timeweb Cloud создала простой и удобный инструмент Timeweb Cloud Apps. С его помощью Next.js-приложение автоматически собирается и публикуется с созданием публичного URL-адреса.
Этот сервис фактически упрощает процесс, заменяя традиционные системы CI/CD, включая и деплой Next.js с использованием Github.
Развернуть его можно всего в несколько кликов. При изменениях в коде на вашем локальном компьютере система автоматически обнаружит новые коммиты в Github, пересоберет приложение и обновит его на сайте. Чтобы это работало, при первом деплое достаточно выбрать опцию «Сборка по последнему коммиту» (см. скриншоты ниже).
Итак, вам не нужно настраивать свои серверы, чтобы показать работу заказчику. Всего за 1 руб. в месяц, мы:
Поскольку вы уже зарегистрированы в Timeweb Cloud, просто перейдите в панели управления в раздел «Apps» → «Создать» и выберите тип приложения «Next.js» и версию Node.js по желанию.
Теперь вам нужно подключить свой GitHub-аккаунт, чтобы платформа могла отслеживать изменения в проекте и автоматически запускать деплой. Дополнительные настройки не требуются — просто нажмите кнопку «Подключить аккаунт» и выберите ваш репозиторий в Github.
Во время подключения вам будет предложено окно авторизации GitHub. Введите свой код авторизации и нажмите кнопку «Подтвердить». Также убедитесь, что переключатель установлен на «Сборка по последнему коммиту».
После авторизации, выберите репозиторий, который вы форкнули (скопировали) к себе в аккаунт и нажмите кнопку «Save».
Вы успешно выполнили два необходимых шага. Теперь нажимайте кнопку «Запустить деплой» (стрелка 3) и наслаждайтесь.
Платформа Timeweb Cloud Apps на ваших глазах соберет приложение, покажет вам весь процесс компиляции приложения и деплоя на сервер.
Поздравляем! Ваше приложение Next.js успешно размещено c в сервисе Timeweb Cloud Apps, и теперь вы можете использовать его без необходимости настройки хостинга. Перейдите в настройки, скопируйте публичный URL и откройте приложение в браузере. Вы также можете изменить адрес на свой собственный, используя кнопку «Редактировать». Затем скопируйте сформированный публичный URL и переходите в браузер.
Теперь разберем подробнее, как устроено и работает наше приложение.
Визуально ваше приложение состоит из блока поисковых слов (по одному слову на строку) и результативной таблицы. Однако этого функционала вполне хватает для того, чтобы читать только те новости, которые вас интересуют.
Исследовав код данного приложения на Next.js, вы научитесь:
Поскольку вы уже скопировали (форкнули) наше приложение в свой репозиторий, теперь мы можем разобраться, из чего оно состоит и как его доработать.
Откройте терминал (для Windows это может быть PowerShell, Windows Terminal или Putty; подробности можно найти в статье). Затем перейдите в папку, где вы храните свои разработки:
cd "/путь/к/папке"
Клонируйте ваше Next.js-приложение на локальный компьютер:
git clone https://github.com/ВАШ_НИК/nextjs-rss-news-filter.git nextjs-rss-news-filter
cd nextjs-rss-news-filter
Установите зависимости:
npm install
Для запуска приложения введите команду:
npm run dev
Откройте ваш трекер в браузере по адресу: http://localhost:3000/
.
Откройте редактор или IDE (например VS Code или Zed) и загрузите ваш проект. Структура каталогов вашего приложения выглядит следующим образом:
Основной каталог, содержащий логику приложения, — это App
. Назначение остальных:
/api/rss/route.js
— это ваш серверный код, который принимает запросы от приложения и отдает ответы. В нашем случае он получает просьбу предоставить код RSS-ленты, затем идет на внешний сервер, получает эту ленту и отдает приложению. Именно благодаря такому механизму вы спокойно обходите ограничения CORS и можете спокойно получать и RSS, и страницы других сайтов (например, для парсинга), и запросы к закрытым API./fonts
— шрифты, используемые в приложении./styles
— набор стилей.layout.js
— базовый шаблон (скелет) страницы. Здесь вы можете внедрить меню, footer и т.д., которые будут использоваться на всех страницах вашего приложения.page.js
— тело главной страницы (у нас одностраничное приложение, поэтому других файлов не будет).Давайте рассмотрим основной файл page.js
и разберем логику (магию) фильтрации новостей по вашему вкусу.
Файл состоит из одного блока export default function Home()
, который содержит внутри наши функции бизнес-логики, а также шаблон отрисовки страницы.
Для работы с мы будем использовать всего 10 функций, которые создают 100% магии нашего приложения на Next.js.
Вложенные функции (методы) и их назначение:
Функция |
Назначение |
|
Преобразование строки с ключевыми словами для поиска в массив |
|
При монтировании загружаем данные из |
|
Сохраняем данные в |
|
Загрузка RSS-ленты |
блок |
Фильтрация новостей по ключевым словам |
|
Обработчик изменения текста в |
|
Показать/скрыть новость при клике по заголовку |
|
Подсветка найденного текста, заголовка, описания, категории |
|
Возвращает готовый рендер страницы по HTML-шаблону |
Функции localStorage.getItem
и localStorage.setItem
предельно просты. Они просто читают или записывают список ваших поисковых слов в хранилище браузера. На них мы не будем останавливаться.
Функция filterWordsArray
— это код JavaScript, который просто переводит ваши поисковые слова в массив и удаляет пустые строки с помощью filter(Boolean)
.
Тело функции:
const filterWordsArray = filterWords
.split('\n')
.map((word) => word.trim().toLowerCase())
.filter(Boolean);
Это наша основная функция. Здесь мы обращаемся к нашему локальному прокси-серверу /api/rss
, который в свою очередь идет в интернет, получает реальную RSS-ленту и отдает нашему приложению. Если вы обратитесь к внешней ленте напрямую, то в 90% случаев получите ограничение CORS, а наш механизм позволяет не обращать внимание на такие мелочи (ведь мы же умные разработчики, нас такое не остановит).
Тело функции:
|
Получаем ленту |
|
Преобразуем ленту (это просто набор текста xml) в DOM-модель, которую понимает браузер, и в которой мы можем манипулировать элементами |
|
Что делаем: Из DOM-документа извлекаются все элементы Все. Теперь мы можем спокойно работать с массивом данных. |
|
Обновляем состояние: Состояние |
|
В случае ошибки при выполнении запроса или парсинга, в состояние |
|
Блок |
Здесь мы обрабатываем текст, очищаем, фильтруем и т.д.
Проверка наличия фильтруемых слов ( |
Если переменная |
Разделение и обработка строк в |
Строка из переменной |
Приведение слов к нижнему регистру и удаление лишних пробелов |
Каждое слово в массиве обрабатывается с помощью |
Фильтрация пустых строк |
С помощью |
Фильтрация RSS элементов на основе ключевых слов |
Выполняется фильтрация элементов |
Проверка наличия совпадений слов с контентом каждого элемента |
Для каждого элемента |
Обновление состояния отфильтрованными элементами |
Результаты фильтрации сохраняются в состоянии |
Обновление состояния при отсутствии ключевых слов |
Если переменная |
Функция в useEffect
динамически фильтрует элементы RSS в зависимости от заданных фильтруемых слов, проверяя их на совпадение в заголовке, описании или категории.
Функции highlightText
, highlightedTitle
, highlightedDescription
, highlightedCategory
почти идентичны. Они раскрашивают в желтый цвет найденные совпадения. Рассмотрим одну из них.
Тело функции:
const highlightedTitle = (title, words) => {
const safeWords = words.map((word) => word.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')); // Экранирование спецсимволов
return <span dangerouslySetInnerHTML={{ __html: highlightText(title, safeWords) }} />;
};
На входе получаем текст заголовка и список слов для поиска. Сначала делаем экранирование спецсимволов. Каждое слово из массива words
обрабатывается с помощью метода replace()
. Регулярное выражение /[.*+?^${}()|[\]\\]/g
находит все специальные символы, которые нужно экранировать. В результате все специальные символы в строке экранируются, что позволяет безопасно использовать их в регулярных выражениях без изменения их смысла.
Экранированные слова сохраняются в массиве safeWords
, который затем используется для выделения текста в функции highlightText
. Это гарантирует, что слова с потенциально опасными символами будут правильно обработаны.
В нашей реализации использован правильный подход, когда мы не обращаемся во внешний интернет напрямую, а делаем это через встроенный прокси-сервер. Такой подход называют прокси-запрос или обращение через серверный прокси.
Этот метод позволяет обращаться к внешним API или ресурсам через свой сервер, выступающий в роли посредника. Прокси может фильтровать, модифицировать запросы и ответы, а также добавлять уровни безопасности и контроля доступа.
Весь сервер состоит из одного файла и 18 строк кода.
Тело app/api/rss/route.js
:
import axios from 'axios';
export async function GET() {
try {
// запасной вариант https://lenta.ru/rss/news
const response = await axios.get('https://www.mk.ru/rss/news/index.xml', {
headers: {
'Content-Type': 'application/xml',
},
});
return new Response(response.data, {
headers: { 'Content-Type': 'application/xml' },
});
} catch (error) {
return new Response('Ошибка при получении данных', { status: error.response?.status || 500 });
}
}
Здесь все просто: при вызове функции GET сервер получает из интернета файл https://www.mk.ru/rss/news/index.xml
и отдает его содержимое нашему приложению. Вот и вся магия. Зато сколько плюсов.
Итак, в данной статье, мы научились создавать среднее по сложности приложение на Next.js и размещать его в публичном пространстве, не создавая собственных серверов и не покупая сложный хостинг.
Для тех, кто только начинает, важно знать, что Next.js — это современный фреймворк для JavaScript, который делает создание веб-приложений намного проще и быстрее. Он помогает приложениям работать быстрее, быть хорошо видимыми в поисковиках и поддерживает как динамическую, так и статическую генерацию страниц. Next.js легко освоить, особенно если вы уже знакомы с React, и он отлично подходит как для новичков, так и для тех, кто хочет разрабатывать приложения на уровне профессионалов.
Timeweb Cloud, в свою очередь, упростит размещение вашего кода в интернете: вы получите удобные и безопасные публичные ссылки на проекты, бесплатные SSL-сертификаты и многое другое. Мы советуем начать с Timeweb Cloud Apps — это идеальная платформа для быстрого старта.
Здесь вы можете спокойно создавать и экспериментировать, не думая о серверах и сложных настройках — об этом позаботятся наши специалисты.