Legacy Ptchr Projects

A guide for migrating from legacy Ptchr Nuxt Statamic to the new Nuxt Statamic module.

Before you start

.npmrc

Make sure you have a GIT_NOBEARS_TOKEN environment variable set in your global .zshrc file.

.zshrc
export GIT_NOBEARS_TOKEN="YOUR_GIT_NOBEARS_TOKEN_ACCESS_TOKEN"

pnpm workspace

If you are using pnpm as your package manager and have a minimumReleaseAge set in your pnpm-workspace.yaml file, please add the following to your file:

pnpm-workspace.yaml
minimumReleaseAgeExclude:
  - "@nobears-front-end/nuxt-statamic"
  - "@nobears-front-end/nuxt-mapbox"
  - "@nobears-front-end/nuxt-multi-tenancy"
  - "@nobears-front-end/eslint"
  - "@nobears-front-end/utils"
  # Any additional internal packages you are using...

Upgrading Nuxt

The new Nuxt Statamic module is only compatible with Nuxt 4.1.0 and higher. Please upgrade your Nuxt version before starting the migration.

Upgrade Nuxt to the latest version

Upgrade Nuxt version to at least v4.1.0

pnpm
npx nuxi@latest upgrade --dedupe

Update your dir structure

Update your projects directory structure to the new Nuxt 4 structure.

Take a look at the Nuxt 4 directory structure for more information.

Update nuxt.config.ts

Update any relative paths to the new directory structure. (e.g. src/ -> app/)

Remove srcDir and experimental configurations.

nuxt.config.ts
export default defineNuxtConfig({
  srcDir: 'src/',  experimental: {}});

Update the nuxt modules to the latest version that support Nuxt 4.

Among others:

  • @nuxt/eslint
  • @nuxt/fonts
  • @nuxt/icon
  • @nuxt/image
  • @nuxt/scripts
  • @nuxtjs/i18n
  • @nuxtjs/seo

Update I18n

Follow the I18n migration guide to update your I18n configuration.

And update your nuxt.config.ts file:

nuxt.config.ts
export default defineNuxtConfig({
  i18n: {
    langDir: "",    vueI18n: "",    restructureDir: true,  },
});

Update TypeScript

Follow the Nuxt 4 TypeScript migration guide to update your TypeScript configuration.

Remove @unhead/vue

And last but not least, remove the @unhead/vue package.

pnpm
pnpm remove @unhead/vue

Migrate the @nobears/statamic-nuxt-theme package

Follow the Statamic Nuxt Theme migration guide to migrate the @nobears/statamic-nuxt-theme package.

Migrating to the new @nobears-front-end/nuxt-statamic module

Remove the old @nobears/statamic module

Uninstall the package

Uninstall the old @nobears/statamic module.

pnpm
pnpm remove @nobears/statamic

Remove the environment variable

Remove the environment variable from your .env file.

.env
STATAMIC_URL="https://your-statamic-api-url.com"

Update the nuxt.config.ts file

nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@nobears/statamic'],});

Add the new @nobears-front-end/nuxt-statamic module

Install the new @nobears-front-end/nuxt-statamic module

You can install the module with your favorite package manager:

pnpm add @nobears-front-end/nuxt-statamic

Add the environment variables

Setting NUXT_DEBUG to true will enable additional logging and debugging information.

Add the CMS url environment variable to your .env file.

.env
NUXT_PUBLIC_STATAMIC_URL="https://your-statamic-api-url.com"

Nuxt Configuration

For all the new available options, please refer to the configuration page.

In order to use the nuxt-statamic module, you need to add the module to your Nuxt config.

nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@nobears-front-end/nuxt-statamic'],});

Remove the deprecated options

  • collections
  • sitemap - (now part of the seo config settings)
nuxt.config.ts
export default defineNuxtConfig({
  statamic: {
    collections: [],    sitemap: true,  },
});

Update the configuration options

Setting seo to true will automatically enable the sitemap.

nuxt.config.ts
export default defineNuxtConfig({
  statamic: {
    navigations: [{
      handle: 'footer',
      fields: 'title,links',      fields: ['title', 'links'],    }],
    seo: true,  },

  seo: {    redirectToCanonicalSiteUrl: true,  },});

Tailwind Configuration

The styling for the <StatamicBlock> component is now handled by the @nobears-front-end/nuxt-statamic module instead of the @nobears/ui package.

app/assets/css/main.css
@import "tailwindcss";
@import "@nobears-front-end/nuxt-statamic";

Breaking changes

Server side $api instance

In the old package, you could access the configured $api.$fetch instance inside server side code to make requests to the Statamic API.

This is no longer possible. You will now need to use the createFetchInstance function instead.

server/api/urls.get.ts
export default 
defineCachedEventHandler
(async (
event
:
H3Event
) => {
const
data
= await
$api
.$fetch(`/api/forms/${form}`);
const
$api
=
createFetchInstance
();
const
data
= await
$api
(`/api/forms/${form}`);
return
data
;
});

useStatamicPage

You will now need to use the useStatamicPageErrorHandler composable to handle the errors from the useStatamicPage composable.

pages/[...slug].vue
<script setup lang="ts">
const { 
data
,
error
} = await
useStatamicPage
();
useStatamicPageErrorHandler
(
error
);
</script>

<StatamicBlock>

You need to read the <StatamicBlock> documentation first before continuing, you will likely miss some important information if you don't.

We have overhauled the StatamicBlock component to make it easier to use and have a more consistent API.

Overview of the new API:

  1. The StatamicBlock is now used inside the "block" component you create for each block type.
    (inside the app/components/blocks directory)
  2. The StatamicBlock no longer supports the background_image prop from the "Block options" fieldset.
  3. The StatamicBlock now exposes fully typed types for the block data and options.
    (StatamicBlockProps and StatamicBlockOptions)

Update usage in your pages

We use a toPascalCase function to convert the block type to a PascalCase string. You can copy the code below, or use the useChangeCase composable from @vueuse/integrations.
<script setup lang="ts">
import { useChangeCase } from '@vueuse/integrations/useChangeCase';

const { data, error } = await useStatamicPage();
useStatamicPageErrorHandler(error);
</script>

<template>
    <StatamicBlock
        v-for="block in data?.blocks"
        :key="block.id"
        :block="block"
    />
    <!-- Using the `toPascalCase` function -->
    <component
        :is="resolveComponent(toPascalCase(block.type))"
        v-for="block in data?.blocks"
        :key="block.id"
        :block="block"
    />
    <!-- Or using the `useChangeCase` composable (the recommended way) -->
    <component
        :is="resolveComponent(useChangeCase(block.type, 'pascalCase'))"
        v-for="block in data?.blocks"
        :key="block.id"
        :block="block"
    />
</template>

Since we removed support for the background_image prop from the "Block options" fieldset, you will need to add the following in order to have the same functionality as before:

app/page/blog/[...slug].vue
<template>
    <component
        v-for="
block
in data?.blocks"
:
key
="
block
.id"
:is="
resolveComponent
(toPascalCase(
block
.type))"
:
block
="
block
"
:
style
="
block
.background_image?.permalink ? {
backgroundImage
: `url('${
block
.background_image?.permalink}')`,
backgroundSize
: 'cover',
backgroundRepeat
: 'no-repeat',
} :
undefined
"
/> </template>

Update usage in your components

We have added types for every fieldtype that Statamic offers. You should use these types in your block components.
app/components/blocks/TextImage.vue
<script lang="ts">
import type { 
StatamicBlockProps
,
TextField
} from "@nobears-front-end/nuxt-statamic";
export type
TextImageProps
=
StatamicBlockProps
<{
title
:
TextField
;
}>; </script> <script setup lang="ts">
defineProps
<
TextImageProps
>();
</script> <template> <StatamicBlock
:
block
>
<!-- Content here --> </StatamicBlock> </template>

Block styling

For more information on how the spacing etc. is controlled, take a look at the Adding custom spacings section.

The styling for the <StatamicBlock> component is now handled by the @nobears-front-end/nuxt-statamic module instead of the @nobears/ui package.

Update the background colors

The background colors are now controlled by the [data-background-color] attribute instead of the [data-bg-color] attribute.

app/assets/css/main.css
@layer components {
    /* list the bg colors that are used in statamic blocks like so */
    [data-bg-color=''] {    [data-background-color=''] {         background-color: var();    }}

Optionally, override the spacing

app/assets/css/main.css
@theme {
    /* Override the default spacing for the small block */
    --spacing-statamic-block-small--md: --spacing(20); }