Создание клиентской части Vue.js для WordPress REST API: пошаговый гайд
Введение
WordPress уже давно превратился в полноценный headless CMS, а REST API позволяет использовать его контент в любой клиентской части. В этой статье мы подробно разберём, как собрать одностраничное приложение (SPA) на Vue.js, которое будет получать данные, управлять авторизацией и кэшировать состояние.
Мы будем использовать JWT‑плагин для безопасной авторизации, Vue Router для навигации и Pinia (или Vuex) для глобального хранилища. В конце покажем, как быстро задеплоить готовый проект.
1. Подготовка WordPress: включаем REST API и JWT‑авторизацию
По умолчанию REST API уже активен, но для работы с защищёнными эндпоинтами понадобится токен. Установите и активируйте плагин JWT Authentication for WP‑API. После этого добавьте в wp-config.php следующие константы:
define('JWT_AUTH_SECRET_KEY', 'your-top-secret-key'); define('JWT_AUTH_CORS_ENABLE', true); Создайте простой эндпоинт для проверки токена:
add_action('rest_api_init', function () { register_rest_route('my/v1', '/ping', array( 'methods' => 'GET', 'callback' => function () { return new WP_REST_Response('pong', 200); }, 'permission_callback' => '__return_true', )); }); Теперь API готово принимать запросы от нашего Vue‑приложения.
2. Инициализация проекта Vue.js
С помощью Vue CLI создаём новый проект:
npm install -g @vue/cli vue create wp-vue-client Выбираем preset с Babel, Router и Pinia. После генерации структура будет выглядеть так:
wp-vue-client/ ├─ public/ ├─ src/ │ ├─ assets/ │ ├─ components/ │ ├─ router/ │ ├─ store/ │ └─ App.vue └─ package.json Не забудьте установить axios для HTTP‑запросов:
npm install axios 2.1. Настройка базового URL
Создайте файл src/api.js и задайте базовый путь к вашему сайту WordPress.
import axios from 'axios'; const api = axios.create({ baseURL: 'https://example.com/wp-json', timeout: 5000, }); export default api; 3. Авторизация и работа с защищёнными эндпоинтами
Для получения JWT‑токена отправляем POST‑запрос к /wp-json/jwt-auth/v1/token с логином и паролем.
// src/store/auth.js (Pinia) import { defineStore } from 'pinia'; import api from '../api'; export const useAuthStore = defineStore('auth', { state: () => ({ token: null, user: null }), actions: { async login(username, password) { const response = await api.post('/jwt-auth/v1/token', { username, password }); this.token = response.data.token; api.defaults.headers.common['Authorization'] = `Bearer ${this.token}`; }, logout() { this.token = null; delete api.defaults.headers.common['Authorization']; }, }, }); После успешного входа все последующие запросы автоматически получают заголовок Authorization. Пример получения списка постов:
// src/services/postService.js import api from '../api'; export const fetchPosts = async () => { const res = await api.get('/wp/v2/posts'); return res.data; }; 3.1. Обновление токена
JWT имеет ограниченный срок жизни. Реализуйте автоматическое обновление, вызывая эндпоинт /jwt-auth/v1/token/refresh (если плагин поддерживает) или повторный login.
4. Маршрутизация и глобальное состояние
Vue Router отвечает за навигацию между страницами: список постов, отдельный пост, профиль пользователя.
// src/router/index.js import { createRouter, createWebHistory } from 'vue-router'; import Home from '../components/Home.vue'; import Post from '../components/Post.vue'; import Profile from '../components/Profile.vue'; const routes = [ { path: '/', name: 'Home', component: Home }, { path: '/post/:id', name: 'Post', component: Post, props: true }, { path: '/profile', name: 'Profile', component: Profile, meta: { requiresAuth: true } }, ]; const router = createRouter({ history: createWebHistory(), routes, }); router.beforeEach((to, from, next) => { const auth = useAuthStore(); if (to.meta.requiresAuth &&!auth.token) { next({ name: 'Home' }); } else { next(); } }); export default router; Для хранения данных о постах удобно использовать Pinia‑модуль postStore. Это избавит от лишних запросов при переходе между страницами.
4.1. Кеширование запросов
Axios‑интерцепторы позволяют кэшировать ответы в localStorage на 5 минут.
api.interceptors.response.use(response => { const cacheKey = `${response.config.url}`; const cached = { data: response.data, timestamp: Date.now() }; localStorage.setItem(cacheKey, JSON.stringify(cached)); return response; }); api.interceptors.request.use(config => { const cacheKey = `${config.url}`; const cached = JSON.parse(localStorage.getItem(cacheKey)); if (cached && Date.now() - cached.timestamp Promise.resolve({ data: cached.data, status: 200, statusText: 'OK', headers: {}, config }); } return config; }); 5. Оптимизация и кэширование состояния в браузере
Помимо интерцепторов, стоит добавить Service Worker для офлайн‑режима. Vue CLI уже умеет генерировать PWA‑плагин:
vue add pwa После установки в vue.config.js задайте кэш‑стратегию для API‑запросов.
module.exports = { pwa: { workboxOptions: { runtimeCaching: [{ urlPattern: new RegExp('^https://example.com/wp-json/'), handler: 'NetworkFirst', options: { cacheName: 'wp-api-cache', expiration: { maxEntries: 50, maxAgeSeconds: 300 } }, }], }, }, }; Эти настройки позволяют ускорить загрузку страниц и снизить нагрузку на сервер, что особенно важно после оптимизации WordPress.
6. Деплой готового Vue‑приложения
Самый простой способ — разместить билд на статическом хостинге (Netlify, Vercel). После сборки выполните:
npm run build Полученные файлы из папки dist загрузите в выбранный сервис. Не забудьте указать в настройках хостинга Redirect all requests to index.html, иначе роутинг не будет работать.
Если ваш сайт находится за CDN, проверьте API Gateway – иногда требуется добавить CORS‑заголовки.
Заключение
Мы создали полностью функциональное SPA на Vue.js, которое взаимодействует с WordPress через REST API, реализует безопасную JWT‑авторизацию, использует роутинг, глобальное состояние и кэширование. Такой подход позволяет отделить фронтенд от бэкенда, ускорить работу сайта и упростить масштабирование.
Дальнейшие шаги: добавить SSR с Nuxt.js, настроить CI/CD и интегрировать веб‑аналитику. Удачной разработки!
📚 Читайте также:
❓ Часто задаваемые вопросы
Как получить JWT‑токен в Vue.js?
Отправьте POST‑запрос к /wp-json/jwt-auth/v1/token с полями username и password. В ответе придёт поле token, которое сохраняется в Pinia и добавляется в заголовок Authorization.
Можно ли использовать Vuex вместо Pinia?
Да, Pinia – современный аналог Vuex, но оба работают одинаково. Для Vue 3 рекомендуется Pinia, так как он легче и поддерживает типизацию.
Как кэшировать запросы к REST API?
Можно использовать axios‑интерцепторы, сохраняющие ответы в localStorage, либо Service Worker через PWA‑плагин, который хранит ответы в Cache API.
Что делать, если запросы блокируются CORS?
Убедитесь, что в wp-config.php включён JWT_AUTH_CORS_ENABLE, а в серверных настройках (например, в Kong или Traefik) прописаны заголовки Access‑Control‑Allow‑Origin.