Создание клиентской части Vue.js для WordPress REST API: пошаговый гайд

a close up of a text description on a computer screen

Введение

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.