# Nuxt 4 у 2026 році: Нова структура каталогів та міграція з Nuxt 3 > Повний посібник з міграції на Nuxt 4: нова структура app/, singleton-шар отримання даних, поверхнева реактивність за замовчуванням, розділення TypeScript-контексту, нормалізовані імена компонентів, Vue Router v5, зміни в управлінні head та контрольний список міграції. - Published: 2026-05-01 - Updated: 2026-05-01 - Author: SharpSkill - Tags: nuxt, vue, migration, typescript, tutorial - Reading time: 10 min --- Nuxt 4 являє собою найбільше архітектурне оновлення фреймворку з моменту виходу третьої версії. Нова структура каталогу `app/`, singleton-модель отримання даних, поверхнева реактивність за замовчуванням та розділений TypeScript-контекст змінюють підхід до організації й супроводу Vue-застосунків. Для розробників, які працюють з екосистемою Vue та Nuxt, глибоке розуміння цих змін є критично важливим як для повсякденної роботи, так і для підготовки до технічних співбесід. У цьому матеріалі розглядається кожна ключова зміна Nuxt 4 з практичними прикладами коду та покроковими інструкціями щодо міграції з Nuxt 3. > **Автоматизований інструмент міграції** > > Nuxt 4 надає офіційний codemod для автоматичної реструктуризації каталогів. Перед початком ручної міграції варто запустити `npx codemod@latest nuxt/4/file-structure`, який автоматизує більшу частину структурних змін. Проте оновлення composable, конфігурація TypeScript та управління мета-тегами потребують ручного втручання. ## Нова структура каталогу app/ Найпомітніша зміна в Nuxt 4 полягає у переміщенні всіх клієнтських та серверних файлів застосунку до спеціалізованого каталогу `app/`. У Nuxt 3 компоненти, сторінки, лейаути, middleware та плагіни розміщувалися безпосередньо в кореневому каталозі проєкту. Nuxt 4 чітко розмежовує код застосунку від конфігураційних файлів, публічних ресурсів та серверного коду. ```text my-nuxt-app/ ├─ app/ │ ├─ assets/ │ ├─ components/ │ ├─ composables/ │ ├─ layouts/ │ ├─ middleware/ │ ├─ pages/ │ ├─ plugins/ │ ├─ utils/ │ ├─ app.vue │ ├─ app.config.ts │ └─ error.vue ├─ content/ ├─ public/ ├─ shared/ # New: code shared between app and server ├─ server/ └─ nuxt.config.ts ``` Новий каталог `shared/` є важливим архітектурним доповненням. Він дозволяє спільно використовувати типи, допоміжні функції та константи між кодом застосунку (`app/`) і серверним кодом (`server/`). У Nuxt 3 розробники змушені були дублювати типи на обох сторонах або створювати тимчасові рішення з відносними шляхами імпорту. Каталог `shared/` вирішує цю проблему на структурному рівні, забезпечуючи єдине джерело істини для спільного коду. Файл `nuxt.config.ts` залишається в кореневому каталозі проєкту й не переміщується до `app/`. Аналогічно, каталоги `server/` та `public/` зберігають свої поточні розташування. Це розмежування чітко визначає зони відповідальності: `app/` містить код, що виконується у браузері та на SSR-сервері, `server/` зберігає бекенд-логіку, а `shared/` слугує мостом між цими двома шарами. ## Покрокова міграція з Nuxt 3 Процес міграції з Nuxt 3 на Nuxt 4 складається з кількох послідовних етапів. Першим кроком є оновлення фреймворку до останньої версії та дедуплікація залежностей. ```bash # Upgrade Nuxt and deduplicate dependencies npx nuxt upgrade --dedupe ``` Далі запускається офіційний codemod, який автоматично реструктурує файлову систему відповідно до нового стандарту. Codemod переносить файли до каталогу `app/`, оновлює шляхи імпорту та адаптує конфігурацію. ```bash # Automate the directory restructuring npx codemod@latest nuxt/4/file-structure ``` Для проєктів, які не можуть одразу перейти на нову структуру каталогів, Nuxt 4 пропонує опцію зворотної сумісності. Налаштування `srcDir` та `dir.app` у конфігурації дозволяє зберегти плоску структуру під час поступового переходу. ```typescript // nuxt.config.ts export default defineNuxtConfig({ srcDir: '.', dir: { app: 'app' }, }) ``` Однак це тимчасове рішення. Команда Nuxt однозначно рекомендує повний перехід на структуру `app/`, оскільки майбутні версії фреймворку оптимізуватимуться саме під цю організацію. Крім того, інструменти екосистеми, зокрема Nuxt DevTools та модулі спільноти, вже починають приймати нову структуру як стандартну. ## Singleton-шар отримання даних та реактивні ключі Nuxt 4 вносить фундаментальну зміну в роботу composable `useAsyncData` та `useFetch`. У Nuxt 3 виклик одного й того ж ключа даних з різних компонентів міг спричинити дублювання мережевих запитів та неузгодженість стану. Nuxt 4 впроваджує singleton-патерн: кожен унікальний ключ даних пов'язується рівно з одним екземпляром отримання даних, незалежно від кількості компонентів, що використовують ці дані. Додатково `useAsyncData` отримує новий параметр `getCachedData` з контекстним об'єктом `ctx`, який повідомляє причину повторного виклику. Це дає змогу точно контролювати, коли використовувати кешовані дані, а коли виконувати новий запит. ```typescript // app/composables/useProductData.ts export function useProductData(productId: string) { return useAsyncData( `product-${productId}`, () => $fetch(`/api/products/${productId}`), { getCachedData: (key, nuxtApp, ctx) => { // ctx.cause tells why the fetch is happening if (ctx.cause === 'refresh:manual') return undefined return nuxtApp.payload.data[key] }, }, ) } ``` Параметр `ctx.cause` може набувати значень `'refresh:manual'` (ручне оновлення, ініційоване розробником), `'refresh:hook'` (оновлення, ініційоване хуком життєвого циклу) або `'navigation'` (навігація між сторінками). Завдяки цьому composable може приймати обгрунтовані рішення щодо стратегії кешування: наприклад, завжди використовувати кеш при навігації, але примусово виконувати запит при ручному оновленні. Singleton-патерн також усуває стани перегонів (race conditions). Коли кілька компонентів одночасно запитують однакові дані, Nuxt 4 виконує лише один запит і розподіляє результат між усіма підписниками. Такий підхід зменшує мережеве навантаження та забезпечує узгодженість даних у всьому застосунку. ## Поверхнева реактивність за замовчуванням Одна з найвпливовіших змін у Nuxt 4 полягає в тому, що дані, повернуті `useAsyncData` та `useFetch`, за замовчуванням обгортаються у `shallowRef` замість `ref`. У Nuxt 3 використовувалася глибока реактивність, а це означало, що будь-яка зміна вкладених властивостей об'єкта автоматично ініціювала оновлення компонента. У Nuxt 4 повторний рендер відбувається лише при повній заміні значення `value`. ```typescript // app/pages/dashboard.vue ``` Ця зміна має прямий вплив на продуктивність. Глибока реактивність створює проксі для кожного вкладеного об'єкта та масиву, що спричиняє значне навантаження на пам'ять та процесор при роботі з великими структурами даних. Поверхнева реактивність повністю усуває ці витрати, оскільки система реактивності Vue відстежує лише посилання верхнього рівня. Для команд, що мігрують з Nuxt 3, це означає необхідність перевірки всіх ділянок коду, де вкладені властивості даних, отриманих через `useFetch` або `useAsyncData`, змінюються безпосередньо. Кожну таку мутацію потрібно замінити повною заміною значення (через spread-оператор) або явним увімкненням глибокої реактивності за допомогою опції `deep: true`. ## Розділення TypeScript-контексту (Context Splitting) Замість єдиного глобального `tsconfig.json` Nuxt 4 розділяє конфігурацію TypeScript на чотири окремі контексти. Кожен контекст має власні правила розв'язання типів, що усуває проблему видимості серверних типів у клієнтському коді та навпаки. ```json { "files": [], "references": [ { "path": "./.nuxt/tsconfig.app.json" }, { "path": "./.nuxt/tsconfig.server.json" }, { "path": "./.nuxt/tsconfig.shared.json" }, { "path": "./.nuxt/tsconfig.node.json" } ] } ``` Контекст `app` охоплює код у каталозі `app/`, включаючи компоненти, сторінки та composable. Контекст `server` обслуговує файли в каталозі `server/` з доступом до типів Node.js та серверних API. Контекст `shared` забезпечує підтримку типів для каталогу `shared/`, видимих як з `app`, так і з `server`. Контекст `node` покриває конфігураційні файли, зокрема `nuxt.config.ts`. Це розділення вимагає зміни способу запуску перевірки типів. Прапорець `-b` (режим компіляції проєктних посилань) для `vue-tsc` стає обов'язковим. ```bash # Before (Nuxt 3) nuxt prepare && vue-tsc --noEmit # After (Nuxt 4) nuxt prepare && vue-tsc -b --noEmit ``` Без прапорця `-b` компілятор TypeScript не розпізнає міжпроєктні посилання й повідомлятиме про помилки відсутніх типів. Це одна з найчастіше пропущених змін під час міграції, яка призводить до збоїв у CI/CD-конвеєрах. ## Нормалізовані імена компонентів та Vue Router v5 Nuxt 4 змінює правила іменування автоматично імпортованих компонентів. Компоненти у підкаталогах тепер отримують імена на основі повного шляху каталогу, а не лише імені файлу. Наприклад, компонент `components/dashboard/MetricsCard.vue` у Nuxt 3 був доступний як `DashboardMetricsCard` або `MetricsCard`. У Nuxt 4 дійсним є лише повне нормалізоване ім'я. Ця зміна безпосередньо впливає на конфігурацію ``, де імена компонентів мають бути явно вказані у масивах `include` або `exclude`. ```vue ``` Необхідно перевірити імена компонентів, використані в `keepalive`, `` та динамічних компонентах (``), на відповідність новим нормалізованим іменам. Інакше KeepAlive припинить кешування компонентів, а анімовані переходи перестануть працювати. Паралельно з цим Nuxt 4 інтегрує Vue Router v5, який вносить зміни в API навігації та механізми навігаційних гардів. Метод `router.resolve()` тепер повертає розширений об'єкт з додатковими метаданими. Навігаційні гарди отримали покращену типізацію параметрів. Командам, що використовують складні патерни маршрутизації, необхідно перевірити сумісність своїх гардів та middleware з новим API. ## Критичні зміни в управлінні head (Unhead v2) Nuxt 4 переходить на Unhead v2, що вносить критичні зміни в управління мета-тегами та елементами ``. Властивості `vmid`, `hid`, `children` та `body`, які використовувалися в Nuxt 3 для визначення й дедуплікації тегів, видалено. ```typescript // app/pages/product/[id].vue ``` Окрім того, деякі плагіни Unhead, зокрема `TemplateParamsPlugin` та `AliasSortingPlugin`, більше не завантажуються за замовчуванням. Якщо проєкт використовує шаблонні параметри у мета-тегах (наприклад, `%s | Назва сайту`), їх необхідно явно зареєструвати як Nuxt-плагін. ```typescript // app/plugins/unhead.ts import { TemplateParamsPlugin, AliasSortingPlugin } from '@unhead/vue/plugins' export default defineNuxtPlugin({ setup() { const unhead = injectHead() unhead.use(TemplateParamsPlugin) unhead.use(AliasSortingPlugin) }, }) ``` Симптом відсутньої реєстрації цих плагінів є досить підступним: шаблони заголовків не обробляються, і користувач бачить необроблений текст із символами `%s` замість сформованого заголовка. Ця проблема може не впливати на роботу застосунку в середовищі розробки, тому її складно виявити, поки не буде проаналізовано SEO-метрики в Google Search Console. ## Контрольний список міграції та типові пастки Нижче наведено повний контрольний список для команд, що мігрують з Nuxt 3 на Nuxt 4. Кожен пункт має бути перевірений та підтверджений перед розгортанням у виробниче середовище. 1. **Оновлення Nuxt** -- запуск `npx nuxt upgrade --dedupe` та перевірка сумісності всіх залежностей з Nuxt 4 2. **Реструктуризація каталогів** -- запуск codemod або ручне переміщення файлів до каталогів `app/`, `shared/` та `server/` 3. **Перевірка шляхів імпорту** -- контроль оновлення всіх шляхів імпорту після переміщення файлів 4. **Оновлення composable отримання даних** -- перегляд усіх використань `useAsyncData` та `useFetch` з урахуванням нового API `getCachedData` та singleton-патерну 5. **Адаптація до shallow reactivity** -- виявлення та виправлення всіх місць, де вкладені властивості даних змінюються безпосередньо 6. **Конфігурація TypeScript** -- оновлення `tsconfig.json` до формату проєктних посилань та перехід `vue-tsc` на режим `-b` 7. **Імена компонентів** -- перевірка відповідності імен у `keepalive`, `` та динамічних компонентах новим нормалізованим іменам 8. **Мета-теги (Unhead v2)** -- видалення застарілих властивостей (`vmid`, `hid`, `children`, `body`) та реєстрація необхідних плагінів 9. **E2E-тести** -- запуск повного набору наскрізних тестів з урахуванням змін навігації Vue Router v5 10. **CI/CD-конвеєр** -- оновлення команд збірки та перевірки типів у конфігурації конвеєра Найтиповіші пастки під час міграції: - **Забуті мутації shallowRef** -- код виду `data.value.property = x`, що безпосередньо змінює вкладені властивості, не ініціює повторний рендер. Це найчастіше повідомлювана проблема після міграції - **Відсутній прапорець `-b`** -- пропуск `-b` у команді `vue-tsc` спричиняє хибні помилки типів, які не видно локально, але з'являються в CI - **Ненормалізовані імена у KeepAlive** -- KeepAlive мовчки ігнорує нерозпізнані імена, що призводить до втрати кешування без видимої помилки - **Відсутні плагіни Unhead** -- непрацюючі шаблони заголовків перетворюються на SEO-проблему, яку можна виявити лише при аналізі результатів Google Search Console Для поглиблення знань з екосистеми Vue та Nuxt рекомендується звернутися до [питання для співбесіди Vue/Nuxt](/technologies/vue-nuxt/interview-questions/nuxt-fundamentals) та [посібник з SSR та статичної генерації](/blog/vue-nuxt/nuxt-3-ssr-static-generation). ## Висновки Nuxt 4 є значним кроком в еволюції фреймворку, що вносить зміни на кожному рівні процесу розробки. Основні висновки для підготовки до міграції та технічних співбесід: - **Нова структура каталогу `app/`** чітко відокремлює код застосунку від конфігурації та серверних ресурсів; каталог `shared/` усуває дублювання типів між клієнтом та сервером - **Singleton-шар отримання даних** забезпечує точний контроль над стратегією кешування через патерн `getCachedData` та контекстний об'єкт `ctx`, запобігаючи дублюванню мережевих запитів - **Поверхнева реактивність за замовчуванням** суттєво підвищує продуктивність для великих структур даних, однак вимагає свідомої адаптації коду, що змінює вкладені властивості - **Розділений TypeScript-контекст** забезпечує строгу ізоляцію типів між клієнтським, серверним та спільним кодом, усуваючи цілий клас типових помилок - **Нормалізовані імена компонентів** та інтеграція Vue Router v5 вимагають перегляду конфігурації KeepAlive, анімованих переходів та навігаційних гардів - **Unhead v2** зобов'язує явно реєструвати шаблонні плагіни та очищати застарілі властивості мета-тегів - **Офіційний codemod** автоматизує реструктуризацію каталогів, проте зміни у composable, TypeScript та мета-тегах потребують ручної перевірки та адаптації --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/uk/blog/vue-nuxt/nuxt-4-directory-structure-migration