Альт-текст помогает людям понять изображение при использовании программы чтения с экрана или когда изображение не может загрузиться. Критерий успеха Web Content Accessibility Guidelines (WCAG) 2.2 1.1.1 требует, чтобы содержательный нетекстовый контент имел текстовую альтернативу, выполняющую ту же цель. Это требование делает визуальную информацию более доступной для восприятия слепыми людьми, людьми с нарушениями зрения или теми, кто использует другие вспомогательные технологии.
В этом уроке вы создадите React-приложение, которое загружает изображение в Cloudinary, генерирует описание с помощью Cloudinary AI, сохраняет это описание вместе с активом и использует его в качестве HTML-атрибута alt изображения. Этот рабочий процесс поддерживает публикацию с учетом требований доступности, делая текстовые альтернативы частью жизненного цикла изображения, а не задачей, которую можно пропустить перед публикацией. Руководство по доступности изображений Cloudinary объясняет, как текстовые альтернативы, централизованные метаданные и создание подписей с помощью ИИ работают вместе.
- Живая демо-версия: https://react-cloudinary-alt-text.vercel.app/
- Исходный код: https://github.com/musebe/react-cloudinary-alt-text
Кратко: Функция анализа контента Cloudinary AI генерирует описание во время загрузки. Пресет загрузки сохраняет это описание во встроенном поле контекстных метаданных alt в Cloudinary. Серверный API считывает изображение и метаданные из Cloudinary. Затем React отображает их оба с помощью AdvancedImage.
Кратко: Функция анализа контента Cloudinary AI генерирует описание во время загрузки. Пресет загрузки сохраняет это описание во встроенном поле контекстных метаданных alt в Cloudinary. Серверный API считывает изображение и метаданные из Cloudinary. Затем React отображает их оба с помощью AdvancedImage.
Altelier — это небольшая студия доступности для изображений в блогах. Она демонстрирует полный жизненный цикл доступного медиаконтента:
- Посетитель загружает изображение с помощью виджета загрузки Cloudinary (Cloudinary Upload Widget).
- Cloudinary сохраняет оригинал в папке активов altelier-blog.
- Функция анализа контента Cloudinary AI генерирует описание.
- Пресет загрузки сохраняет описание как контекст context.custom.alt.
- Приложение считывает сохраненное значение через Admin API Cloudinary.
- React отображает изображение с сохраненным описанием.
- Библиотека доступности определяет изображения с отсутствующим альт-текстом.
Важное проектное решение заключается в том, что изображение и его описание имеют единый источник достоверных данных. Cloudinary хранит оба элемента, поэтому другой веб-сайт, мобильное приложение или система управления контентом могут повторно использовать одно и то же проверенное описание.
Cloudinary рекомендует свое встроенное поле контекстных метаданных alt для централизованных текстовых альтернатив. Подробнее читайте в руководстве по доступности изображений Cloudinary.
HTML-атрибут alt существует на одной отрисованной странице. Контекстные метаданные Cloudinary принадлежат самому активу. Если редактор улучшает описание в Cloudinary, каждое подключенное приложение может запросить обновленное значение вместо поддержки отдельных копий.
Cloudinary не вставляет метаданные автоматически на каждую HTML-страницу. Ваше приложение по-прежнему решает, является ли изображение информативным, функциональным или декоративным. Затем оно сопоставляет сохраненное значение с правильным атрибутом alt во время рендеринга.
Перед началом убедитесь, что у вас есть:
- Node.js версии 20.19 или новее.
- Бесплатная учетная запись Cloudinary.
- Включенная функция анализа контента Cloudinary AI для вашей среды продукта.
- Базовое знакомство с React и TypeScript.
В этом проекте используются React, Vite, shadcn/ui, виджет загрузки Cloudinary, React SDK от Cloudinary и Node.js SDK от Cloudinary.
Начните с генератора проектов React от Cloudinary, затем инициализируйте shadcn/ui:
Установите зависимости проекта и запустите локальное приложение:
В репозитории также используются ресурсы агентов Cloudinary во время разработки. Вы можете узнать, как их подключить, в документации по серверам и навыкам MCP Cloudinary.
Пресет загрузки — это сохраненная группа правил загрузки. Браузер отправляет имя своего пресета с каждым запросом на загрузку, и Cloudinary применяет настроенную папку, форматы, анализ и поведение метаданных.
Откройте консоль Cloudinary → Настройки (Settings) → Загрузка (Upload) → Пресеты загрузки (Upload presets), затем выберите Добавить пресет загрузки (Add upload preset).
Используйте эти настройки на вкладке Общие (General):
React-приложение отправляет имя пресета вместо отправки каждого параметра загрузки из браузера. Cloudinary ищет пресет и применяет его настройки. Это обеспечивает согласованность размещения в папках, создания подписей, ограничений файлов и поведения метаданных при всех загрузках.
В демо-версии используется неподписанный пресет, поскольку браузер загружает файлы напрямую через виджет загрузки Cloudinary. Браузеру нужны только имя облака (cloud name) и имя пресета. Он никогда не получает секретный ключ API Cloudinary.
Неподписанный пресет хорошо подходит для публичной демо-версии с жесткими ограничениями по формату и размеру. Его имя остается видимым в коде браузера, поэтому другой человек может использовать его повторно для загрузки нежелательных файлов.
Используйте подписанную загрузку, когда вашему приложению необходимо:
- Требовать аутентификацию аккаунта перед загрузкой.
- Устанавливать конфиденциальные параметры загрузки на сервере.
- Применять правила папок или доступа для каждого пользователя.
- Предотвращать повторное использование конфигурации загрузки кем-либо за пределами вашего приложения.
Подписанные загрузки требуют серверной конечной точки, которая создает недолговечную подпись. В остальной части этого урока используется неподписанный пресет, чтобы сосредоточиться на рабочем процессе обеспечения доступности.
В разделе Оптимизация и доставка (Optimize and Deliver) установите для параметра Разрешенные форматы (Allowed formats) значение:
Оставьте поля Входящая трансформация (Incoming transformation), Предварительные трансформации (Eager transformations) и Формат (Format) пустыми. Это сохраняет исходную загрузку. Cloudinary может создавать оптимизированные варианты доставки, когда их запрашивает браузер.
Откройте вкладку Аддоны (Addons) пресета. В разделе обработки мультимедиа с помощью ИИ (AI media processing) найдите Анализ контента Cloudinary AI (Cloudinary AI Content Analysis) и включите добавление ИИ-описаний к вашему изображению (Add AI captioning to your image).
Если эта опция недоступна, сначала оформите подписку на аддон в своей учетной записи Cloudinary. Документация по анализу контента Cloudinary AI описывает регистрацию и поддерживаемые функции анализа.
Во время загрузки пресет запрашивает создание ИИ-описания у функции анализа контента Cloudinary AI. Служба анализирует видимые объекты, обстановку и действия, а затем добавляет описание на естественном языке к информации о загрузке. Руководство по аддонам цифрового управления активами (DAM) Cloudinary объясняет, где сгенерированные описания появляются в Медиабиблиотеке (Media Library).
Создание подписей во время загрузки работает лучше всего, когда новые активы должны поступать в вашу библиотеку с черновиком описания. Если у вас уже есть большая Медиабиблиотека, используйте обновление через API или рабочий процесс создания подписей Cloudinary MediaFlows для обработки существующих активов.
ИИ-описания — это отправная точка, а не замена редакционной проверки. Полезное альт-описание зависит от назначения изображения и окружающего контента. Помечайте декоративные изображения пустым атрибутом alt="" вместо их описания.
Описание описывает видимый контент. Альт-текст передает назначение изображения в его текущем контексте. Эти цели пересекаются, но они не идентичны.
Например, ИИ может выдать: «Человек с красным зонтом возле вокзала». Это описание может подойти для статьи о путешествиях. Если изображение является ссылкой на предупреждения о погоде, полезной альтернативой может быть «Посмотреть текущие предупреждения о погоде». Рассматривайте сгенерированное описание как черновик, который редактор может оставить, сократить или заменить.
Генерация описания — это лишь половина рабочего процесса. Описание должно оставаться доступным после того, как ответ о загрузке исчезнет.
Откройте вкладку Дополнительно (Advanced) пресета и добавьте этот скрипт при успехе (On success script):
Этот скрипт выполняет две задачи:
- Он записывает описание во встроенное поле Описание (alt) в Cloudinary.
- Она добавляет тег autogenerated-alt для фильтрации и проверки.
e.upload_info содержит полный ответ о загрузке. Скрипт следует по пути ответа к captioning.data.caption, проверяет наличие текста и вызывает current_asset.update(). Затем Cloudinary сохраняет описание и тег для того же ресурса.
Обратный вызов виджета загрузки существует только в текущей сессии браузера. Обновление страницы удаляет это состояние JavaScript. Сохранение подписи в качестве контекстных метаданных делает ее доступной через Медиабиблиотеку, Admin API, Search API и будущие приложения.
Это условие также защищает рабочий процесс. Cloudinary добавляет тег autogenerated-alt только тогда, когда функция создания подписей возвращает текст. Тег фиксирует способ создания описания, а не то, одобрил ли его человек. Редакторы могут использовать его в качестве очереди на проверку, а не воспринимать каждый загруженный файл как успешно проверенный.
Сохраните пресет. Полная конфигурация консоли записана в руководстве по рабочему процессу alt-text проекта.
Создайте файл .env на основе .env.example, затем добавьте следующие значения:
Два значения с префиксом VITE_ безопасны для браузера. Виджету загрузки требуются имя облака и имя неподписанного пресета.
Ключ API и секретный ключ выполняют аутентификацию запросов Admin API. Храните их на сервере, исключите .env из Git и никогда не добавляйте префикс VITE_ к секретному ключу. ALTELIER_DELETE_TOKEN защищает деструктивное действие галереи в демоверсии. Это не учетные данные Cloudinary.
В руководстве по SDK Cloudinary для Node.js рассматривается настройка как на основе переменных окружения, так и на основе кода.
Загрузка с помощью неподписанного пресета — это операция на стороне браузера. Поиск метаданных приватных ресурсов, чтение содержимого папок и удаление ресурсов — это доверенные операции на стороне сервера. Vite включает каждую переменную VITE_ в пакет браузера, что означает, что посетители могут просматривать эти значения.
Храните CLOUDINARY_API_SECRET на сервере Express или в функции Vercel. React вызывает ваши маршруты /api, а эти маршруты обращаются к Cloudinary. Такая граница позволяет интерфейсу использовать функции управления Cloudinary без раскрытия учетных данных аккаунта.
Виджет загрузки принимает локальные файлы, снимки с камеры и удаленные URL-адреса. Для основной конфигурации нужны имя облака и пресет:
Виджет генерирует события для открытия, добавления в очередь, загрузки, успешного завершения и сбоя. Обрабатывайте только событие успешного завершения как завершенный ресурс. Его ответ содержит public_id, размеры, формат, URL для доставки и информацию о подписи.
Altelier сохраняет public_id, так как он является стабильным входным данными для трансформаций доставки Cloudinary. Затем интерфейс запрашивает метаданные ресурса с сервера. Этот второй запрос подтверждает, что Cloudinary сохранила как описание, так и тег, прежде чем приложение сообщит об успехе.
См. полную реализацию UploadWidget.tsx: (https://github.com/musebe/react-cloudinary-alt-text/blob/main/src/cloudinary/UploadWidget.tsx
См. полную реализацию UploadWidget.tsx: (
Код браузера не должен вызывать аутентифицированный Admin API. Altelier использует небольшой API на базе Express с SDK Cloudinary для Node.js.
Сервер выполняет поиск только в папке altelier-blog и запрашивает поля, необходимые для интерфейса:
Search API от Cloudinary поддерживает выражения для папок, тегов, контекстных метаданных, форматов, размеров и дат. Altelier выполняет сортировку по времени создания, чтобы четыре самых новых изображения отображались первыми.
Используйте Search API, когда вам нужна коллекция, например каждое изображение в папке или каждый ресурс, у которого отсутствуют метаданные. Используйте метод ресурсов Admin API, когда вы уже знаете один public_id и хотите проверить этот ресурс.
Altelier использует оба подхода. Галерея выполняет поиск по папке, а проверка после загрузки запрашивает один ресурс. Оба вызова выполняются на сервере, так как требуют аутентифицированного доступа к управлению Cloudinary.
Ответ загрузки и Search API могут возвращать контекстные метаданные в немного отличающихся форматах. Сервер принимает оба варианта:
См. все маршруты API, проверки папок и меры предосторожности при удалении: https://github.com/musebe/react-cloudinary-alt-text/blob/main/server/app.ts
См. все маршруты API, проверки папок и меры предосторожности при удалении:
React SDK от Cloudinary создает доставляемое изображение на основе его public_id. c_fit сохраняет изображение полностью видимым в пределах заданных границ. f_auto выбирает формат, поддерживаемый браузером, а q_auto находит баланс между визуальным качеством и размером файла.
Плагин responsive() запрашивает размер изображения, подходящий под отображаемую ширину. Размытый заполнитель улучшает состояние загрузки, а явные размеры уменьшают смещение макета.
См. руководство по трансформации изображений в React и руководство по оптимизации изображений в Cloudinary.
См. руководство по трансформации изображений в React и руководство по оптимизации изображений в Cloudinary.
c_fit изменяет размер изображения в пределах максимальной ширины и высоты без удаления содержимого. Используйте его, когда важно изображение целиком, например для редакционной графики, плакатов или снимков экрана. Используйте режим обрезки, такой как c_fill, только тогда, когда заполнение рамки важнее сохранения каждого края.
f_auto считывает поддерживаемые браузером форматы и может доставлять такие форматы, как AVIF или WebP. q_auto анализирует изображение и выбирает качество кодирования, которое обеспечивает баланс между размером файла и визуальным качеством. Эти трансформации влияют на доставляемую версию, в то время как исходный ресурс остается доступным в Cloudinary.
Altelier отображает размытую декоративную копию позади изображений, которые не заполняют рамку витрины. На переднем плане используется сохраненное описание. Для декоративного фона используются alt="" и aria-hidden="true".
Просмотреть полный компонент галереи: https://github.com/musebe/react-cloudinary-alt-text/blob/main/src/components/asset-library.tsx
Просмотреть полный компонент галереи:
Просмотреть примеры для Portable React, HTML, Vue и систем управления контентом: https://github.com/musebe/react-cloudinary-alt-text/blob/main/src/components/integration-code-panel.tsx
Просмотреть примеры для Portable React, HTML, Vue и систем управления контентом:
Проверьте результат от загрузки до отрисованного HTML:
- Запустите npm run dev.
- Откройте студию загрузки.
- Загрузите изображение с четким объектом.
- Дождитесь сохранения замещающего текста (Alt text) в Cloudinary.
- Откройте ресурс в Медиабиблиотеке Cloudinary.
- Убедитесь, что поле «Описание (alt)» содержит подпись.
- Убедитесь, что поле «Теги» содержит autogenerated-alt.
- Осмотрите отрисованное изображение и проверьте его атрибут alt.
- Проверьте ресурс в библиотеке специальных возможностей (Accessibility library).
Эти проверки охватывают три разных уровня. Виджет загрузки подтверждает, что Cloudinary приняла файл. Медиабиблиотека подтверждает, что генерация подписей и скрипт успешного завершения сохранили метаданные. Проверка в браузере подтверждает, что React использовал сохраненное описание в финальном HTML.
Если изображение загружается без описания, убедитесь, что приложение использует тот же пресет, который вы отредактировали. Также убедитесь, что параметры «Добавить ИИ-подпись к изображению» (Add AI captioning to your image) и скрипт при успешном завершении (On success script) сохранены.
Репозиторий включает функцию Vercel для /api/* и продакшн-сборку Vite. Перед развертыванием добавьте все переменные из .env.example в проект Vercel. Не добавляйте PORT, так как Vercel управляет средой выполнения функций.
Vite считывает переменные VITE_ при сборке фронтенда. Функции Vercel считывают переменные сервера при обработке запросов API. Добавьте обе группы перед запуском продакшн-деплоя, а затем перезапускайте деплой при каждом изменении переменной фронтенда.
Выполняйте эти проверки перед каждым деплоем:
Следуйте руководству по развертыванию на Vercel для настройки областей видимости окружения и проверок продакшна.
Следуйте руководству по развертыванию на Vercel для настройки областей видимости окружения и проверок продакшна.
Alt-текст не должен быть спонтанной доработкой для отдельной страницы. Храните описание вместе с изображением, сделайте отсутствующие описания видимыми и проверяйте результаты работы ИИ перед публикацией.
Cloudinary может управлять загрузкой, генерацией подписей, метаданными, адаптивной трансформацией и оптимизированной доставкой. React требуется только срендерить нужный ресурс с правильным описанием.
Изучите репозиторий с исходным кодом Altelier, попробуйте интерактивную студию доступности и сравните этот рабочий процесс с оригинальной статьей Cloudinary об автоматической генерации alt-текста для изображений.












