Автор: Джозеф Чеге
Strapi — это безголовая CMS с открытым исходным кодом, основанная на Node.js. Он позволяет разрабатывать и управлять любым содержимым вашего приложения. Это позволяет быстрее создавать серверный API с преимуществами эффективности и настраиваемости.
Что такое Ремикс?
С другой стороны, Remix — хороший выбор для использования ваших сгенерированных конечных точек API. Он предлагает загрузку данных на стороне сервера. Remix — это фреймворк для рендеринга на стороне сервера. Это позволяет без проблем работать с сервером и клиентом. Remix очень похож на фреймворк Next.js.
Ремикс против Next.js
Next.js — одна из популярных платформ React для рендеринга на стороне сервера. Традиционно приложения React отображаются на стороне клиента. Когда первоначальный запрос отправляется из веб-приложения, браузеру отправляется оболочка пустой HTML-страницы без предварительно обработанного содержимого. Браузер, наконец, получит файл JavaScript, отвечающий за рендеринг фактической HTML-страницы.
С введением фреймворков рендеринга на стороне сервера (SSR), таких как Next.js и Remix, страница полностью визуализируется по запросу на сервере. Этот подход подходит для динамического контента, который часто меняется.
Вот некоторые из причин, по которым Remix является хорошим выбором:
- Это быстрее, чем Next.js.
- Ремикс имеет лучшую производительность.
- Remix использует встроенные функции браузера. Это позволяет Remix повторно использовать большинство функций HTML и HTTP на уровне платформы для обработки сложных мутаций. С другой стороны, если приложение Next.js отключается, страница не будет отвечать, что затрудняет обработку мутаций.
- Ремикс использует собственный HTML и может работать без JavaScript. Это упрощает обработку ошибок на сервере, обеспечивая удобство для пользователя.
Remix и Next.js тесно связаны, и разница между ними минимальна. Ознакомьтесь с этим руководством, чтобы получить более полное представление о том, чем Remix отличается от Next.js.
Предпосылки
Чтобы продолжить в этой статье, важно иметь следующее:
- Среда выполнения Node.js, установленная на вашем компьютере,
- Базовые знания JavaScript и
- Предыдущий опыт работы с фреймворком на основе React, таким как Remix.
Локальная настройка Strapi
Давайте погрузимся и создадим серверную часть Strapi CMS. Это будет обслуживать сообщения блога для пользователей. Чтобы настроить Strapi CMS, создайте папку проекта. Затем откройте команду, указывающую на этот каталог, желательно с помощью текстового редактора, такого как Visual Studio Code. Выполните следующую команду, чтобы установить Strapi CMS на локальный компьютер:
npx create-strapi-app@latest blog-app
Обязательно выполните эту команду на основе следующего типа установки:
Это создаст папку blog-app
, в которой будут храниться все файлы проекта и зависимости, которые Strapi CMS потребуется запускать локально. После завершения установки вы будете перенаправлены на страницу администрирования Strapi в браузере по умолчанию http://localhost:1337/admin/auth/register-admin
.
Укажите учетные данные для входа в систему администратора Strapi. Если вы еще не создали учетную запись, укажите регистрационные данные. Наконец, нажмите кнопку Начать, чтобы получить доступ к панели администратора.
Создайте коллекцию блогов с помощью Strapi CMS
Здесь мы создаем приложение для блога. Следовательно, нам нужно смоделировать содержимое серверной части приложения для блога с помощью Strapi. Первым шагом является настройка типа контента. В административной панели Strapi нажмите Content-Type Builder.
Затем нажмите кнопку + Создать новый тип коллекции, чтобы настроить коллекцию. Введите blog
в качестве имени типа контента:
Нажмите Продолжить и настройте следующие поля блога:
- Заголовок в виде короткого текста — краткий заголовок для вашего сообщения в блоге.
- Отрывок в виде длинного текста — краткое изложение вашего сообщения, которое будет отображаться в веб-приложении.
- Hero: выберите медиафайл, один — описательное изображение для вашего сообщения в блоге.
- Контент: как форматированный текст — представляет содержание вашего сообщения в блоге.
Наконец, создайте тестовый контент для вышеуказанной коллекции и ее полей. Нажмите кнопку + Создать новую запись:
Заполните все поля, а затем убедитесь, что вы публикуете добавленный контент:
Убедитесь, что вы создали как минимум три разных сообщения в блоге, используя ту же процедуру, что описана выше.
Добавление ролей и разрешений
Strapi CMS использует несвязанную структуру приложений. Чтобы получить доступ к его содержимому, вам необходимо настроить разрешения и роли, которые определяют, какие данные должны быть доступны для ваших пользовательских каналов.
В этом примере нам нужен Remix для взаимодействия с созданной нами коллекцией. Таким образом, нам нужно настроить доступ к этой коллекции, чтобы Remix мог выполнить правильный запрос и получить ожидаемые ответы.
Чтобы получить доступ к созданной коллекции blog
, создайте токен API, который Remix будет использовать для связи со Strapi. Чтобы создать токен:
- Перейдите в раздел Настройки на панели управления Strapi.
- Щелкните раздел Токены API.
- Нажмите кнопку «Создать новый токен API», чтобы установить токен для использования API.
Введите имя и описание в соответствующие поля. Наконец, выберите тип токена Только для чтения и нажмите «Сохранить».
В этом примере Remix будет читать только содержимое нашей коллекции. Если вам нужно добавить такие операции, как запись в Strapi CMS, убедитесь, что вы изменили тип токена соответствующим образом.
Токен API будет сгенерирован. Скопируйте созданный токен, так как мы будем использовать его с Remix.
Настройка приложения Remix
Теперь давайте создадим внешнее приложение для использования контента, созданного с помощью Strapi. В каталоге вашего проекта, который вы создали ранее, выполните следующую команду, чтобы настроить Remix:
npx create-remix@latest remix-blog-app
Приведенная выше команда создаст папку remix-blog-app
, в которой будут размещены все файлы проекта и зависимости, которые потребуются Remix для запуска локального веб-приложения.
После завершения установки перейдите во вновь созданный каталог:
cd remix-blog-app
Вы можете проверить, правильно ли работает созданное приложение Remix, запустив:
npm run dev
Откройте http://localhost:3000/
в браузере, и вы увидите приветственную версию веб-приложения Remix.
В корневом каталоге Remix проекта (remix-blog-app
) создайте файл .env
и добавьте следующие конфигурации Remix:
STRAPI_API_TOKEN="your_access_token"
STRAPI_URL_BASE="http://your_local_ip_address:1337"
Вставьте свой токен доступа с панели управления Strapi, чтобы заменить your_access_token
.
Настройка компонентов ремикса
Компоненты задают пользовательский интерфейс приложения. Remix использует компоненты для настройки различных разделов веб-приложения. Здесь будут созданы следующие компоненты:
- Панель навигации: базовая панель навигации веб-приложения.
- Карточки сообщений в блогах: карточки ремиксов для отображения сообщений и их свойств.
- Макет: чтобы установить общий макет веб-страницы.
Чтобы настроить эти компоненты, создайте папку components
в каталоге app
проекта Remix. Внутри папки components
создайте следующие файлы и соответствующие блоки кода для создания компонентов:
Navbar.jsx
:
export default function Navbar() {
return (
<nav className="navbar">
<div className="nav-wrapper">
<a href="/" className="brand-logo">Blog App</a>
</div>
</nav>
)
}
Здесь мы создаем Navbar
, который отображает логотип бренда приложения в виде текста Blog App
. Щелчок по этому логотипу бренда перенаправит пользователя на домашнюю страницу приложения.
BlogCard.jsx
:
import { Link } from '@remix-run/react';
import url from '../utils/url';
export default function BlogCard({ blog }) {
let data = blog.attributes;
return (
<div className="card">
<div className="card-content">
<div className="card-img">
<img src={`${url}${data.hero.data.attributes.url}`} alt={data.hero.data.attributes.alternativeText} />
</div>
<div className="card-details">
<Link to={`/posts/${blog.id}`} className="card-title">
{data.title}
</Link>
<p className="card-excerpt">{data.excerpt}</p>
</div>
</div>
</div>
)
}
Это BlogCard
будет отображать и упорядочивать блоги в вашем приложении. Здесь каждая открытка будет отображать заголовок поста, главное изображение и отрывок поста.
Layout.jsx
:
import Navbar from './Navbar';
export default function Layout({ children }) {
return (
<div style={{ fontFamily: "system-ui, sans-serif", lineHeight: "1.4" }}>
<Navbar />
<div className="container">
{children}
</div>
</div>
);
}
Компонент Layout
запускает контейнер, который оборачивает компонент Navbar в основное приложение.
style.css
Чтобы стилизовать вышеуказанные компоненты, добавьте следующий код CSS в файл style.css
:
/* Navbar */
.navbar {
box-shadow: 0 1px 0 rgba(0, 0, 0, 0.05);
margin-bottom: 0;
padding: 12px;
position: relative;
}
.navbar .nav-wrapper a {
text-decoration: none;
font-size: 20px;
}
/* Layout */
.container {
width: 50%;
margin: 0px auto;
}
/* Blog card */
.card {
width: 100%;
padding: 10px;
margin: 10px 0px;
border-radius: 5px;
box-shadow: 0 1px 3px 0 #d4d4d5, 0 0 0 1px #d4d4d5;
}
.card-content {
width: 100%;
display: flex;
justify-content: space-between;
}
.card-content .card-img {
width: 50%;
height: 100%;
}
.card-img img {
width: 90%;
height: 100%;
border-radius: 5px;
}
.card-details .card-title {
text-decoration: none;
}
index.jsx
:
Чтобы выполнить вышеуказанные компоненты, создайте файл index.jsx
и экспортируйте его, как показано в следующем блоке кода:
import BlogCard from "./BlogCard";
import Layout from "./Layout";
import Navbar from "./Navbar";
export { BlogCard, Layout, Navbar };
Экспорт этих компонентов упрощает доступ к ним и их использование другими модулями приложения.
Настройка утилит для ремиксов
Создайте папку utils
внутри каталога Remix app
. Внутри папки utils
создайте следующие файлы:
errorHandling.js
: Для обработки исключений при подключении к серверному API Strapi:
// Custom error class for errors from Strapi API
class APIResponseError extends Error {
constructor(response) {
super(`API Error Response: ${response.status} ${response.statusText}`);
}
}
export const checkStatus = (response) => {
if (response.ok) {
// response.status >= 200 && response.status < 300
return response;
} else {
throw new APIResponseError(response);
}
}
class MissingEnvironmentVariable extends Error {
constructor(name) {
super(`Missing Environment Variable: The ${name} environment variable must be defined`);
}
}
export const checkEnvVars = () => {
const envVars = [
'STRAPI_URL_BASE',
'STRAPI_API_TOKEN'
];
for (const envVar of envVars) {
if (!process.env[envVar]) {
throw new MissingEnvironmentVariable(envVar)
}
}
}
url.js
: URL-адрес локального хоста хоста Strapi.
export default "http://localhost:1337";
Настройка маршрутов
Чтобы получить доступ к сообщениям, мы создадим маршруты Remix. В этом случае у нас будет два основных маршрута:
- Направьте один, чтобы получить все сообщения.
- Второй маршрут, который является дочерним маршрутом для каждого сообщения, чтобы помочь нам получить доступ к одному сообщению.
Давайте создадим эти маршруты.
Получение всех сообщений
Перейдите к файлу app/routes/index.jsx
и извлеките все записи блога следующим образом:
- Импортируйте все необходимые модули:
import { useLoaderData } from '@remix-run/react';
import { checkEnvVars, checkStatus } from '../utils/errorHandling';
import {Layout, BlogCard} from '../components';
import styles from '../components/style.css';
- Настройте стили для компонента BlogCard:
export const links = () => [
{ rel: "stylesheet", href: styles },
];
- Настройте загрузчик для загрузки сообщений из Strapi:
export async function loader() {
checkEnvVars(); // check environmental variables
const response = await fetch(`${process.env.STRAPI_URL_BASE}/api/blogs?populate=hero`, {
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.STRAPI_API_TOKEN}`,
"Content-Type": "application/json"
}
}); // get the blogs
checkStatus(response); // check the status
const data = await response.json(); // get the json response
if (data.error) { // error check
throw new Response("Error loading data from strapi", { status: 500 });
}
return data.data; // return the data
}
- Отредактируйте функцию рендеринга, чтобы получать сообщения и отображать их в компоненте BlogCard:
export default function Index() {
const blogs = useLoaderData();
return (
<Layout>
{
blogs.length > 0 ? (
blogs.map(blog => (
<BlogCard key={blog.id} blog={blog} />
))
) : (
<p>No blog posts found!</p>
)
}
</Layout>
);
}
Этого будет достаточно для отображения постов в блоге на Remix. Чтобы проверить, работает ли он должным образом, убедитесь, что сервер разработки Remix запущен и работает, используя следующую команду:
npm run dev
Это послужит вашей заявке на http://localhost:3000
. Воспользуйтесь этой ссылкой и откройте приложение в браузере. В зависимости от добавленных сообщений ваша страница должна быть похожа на:
Получение отдельного поста
На этом этапе Remix может обслуживать сообщения в блоге. Однако мы не можем получить доступ к содержимому каждого отдельного сообщения. Для этого:
- Создайте каталог
posts
внутри каталогаapp/routes
. - Создайте файл
$postId.jsx
в каталогеposts
. - В файл
$postId.jsx
импортируем необходимые модули:
import { useLoaderData } from '@remix-run/react';
import { checkEnvVars, checkStatus } from '../../utils/errorHandling';
import url from '../../utils/url';
import { Layout } from '../../components';
import styles from '../../components/style.css';
- Настройте стили:
export const links = () => [
{ rel: "stylesheet", href: styles },
];
- Настройте функцию загрузчика для получения каждого сообщения:
export async function loader({ params }) {
const { postId } = params; // get the post id
checkEnvVars(); // check the environmental variables
const response = await fetch(`${process.env.STRAPI_URL_BASE}/api/blogs/${postId}?populate=hero`, {
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.STRAPI_API_TOKEN}`,
"Content-Type": "application/json"
}
}); // send a request to strapi backend to get the post
checkStatus(response); // check the response status
const data = await response.json(); // get the json data
if (data.error) {// check if we have an error
throw new Response("Error loading data from strapi", { status: 500 });
}
return data.data; // return the data
}
- Настройте функцию рендеринга, чтобы получить данные и отобразить их:
export default function Post() {
const blog = useLoaderData();
const blogData = blog.attributes;
return (
<Layout>
<div className="blog-post">
<div className="blog-post-hero">
<img src={`${url}${blogData.hero.data.attributes.url}`} alt={`${blogData.hero.data.attributes.alternativeText}`} />
</div>
<div className="blog-post-title">
<h1>{blogData.title}</h1>
</div>
<div className="blog-post-content">
<div dangerouslySetInnerHTML={{ __html: blogData.content }} />
</div>
</div>
</Layout>
)
}
Убедившись, что сервер разработки запущен и работает, щелкните любой пост на домашней странице. Вы будете перенаправлены на страницу с содержанием каждого конкретного блога, как показано ниже:
Заключение
Strapi CMS используется для разработки и управления контентом любого приложения. Это помогает вам быстрее формировать любой API и использовать контент через Restful API и GraphQL. В этом руководстве мы создали Strapi Restful API, а затем использовали его для создания минималистического приложения для блога Remix.
Вы можете получить исходный код, используемый в этом проекте, в репозитории GitHub для части Remix Frontend.