# Migrating to v7

This guide covers the changes you need to make when upgrading from Blockstudio 6 to 7.

## ES Module Imports

### New `npm:` Prefix (Recommended)

Blockstudio 7 introduces a new `npm:` prefix for ES module imports, aligning with [Deno's npm specifier](https://docs.deno.com/runtime/fundamentals/node/#using-npm-packages) convention.

**Before (v6):**

```javascript
import { h, render } from "blockstudio/preact@10.15.1";
import htm from "blockstudio/htm@3.1.1";
import confetti from "blockstudio/canvas-confetti@1.6.0";
```

**After (v7):**

```javascript
import { h, render } from "npm:preact@10.15.1";
import htm from "npm:htm@3.1.1";
import confetti from "npm:canvas-confetti@1.6.0";
```

### CSS Imports

The same change applies to CSS imports:

**Before (v6):**

```javascript
import "blockstudio/swiper@11.0.0/swiper.min.css";
```

**After (v7):**

```javascript
import "npm:swiper@11.0.0/swiper.min.css";
```

### Backward Compatibility

The `blockstudio/` prefix is still supported for backward compatibility. Your existing code will continue to work without changes. However, we recommend migrating to the `npm:` prefix for consistency with the broader JavaScript ecosystem.

The `npm:` prefix offers several advantages:

- **Ecosystem alignment** - Matches Deno's established convention
- **Clarity** - Makes it immediately clear you're importing from npm
- **Future-proofing** - The `blockstudio/` prefix may be deprecated in a future major version

## Hook Names

Blockstudio 7 standardizes all PHP hook names to use `snake_case` instead of `camelCase`, aligning with WordPress core conventions.

### Changed Hook Names

| Old Name (v6) | New Name (v7) |
|---------------|---------------|
| `blockstudio/blocks/components/useblockprops/render` | `blockstudio/blocks/components/use_block_props/render` |
| `blockstudio/blocks/components/innerblocks/render` | `blockstudio/blocks/components/inner_blocks/render` |
| `blockstudio/blocks/components/innerblocks/frontend/wrap` | `blockstudio/blocks/components/inner_blocks/frontend/wrap` |
| `blockstudio/blocks/components/richtext/render` | `blockstudio/blocks/components/rich_text/render` |
| `blockstudio/assets/process/scss/importPaths` | `blockstudio/assets/process/scss/import_paths` |
| `blockstudio/settings/assets/process/scssFiles` | `blockstudio/settings/assets/process/scss_files` |
| `blockstudio/settings/editor/formatOnSave` | `blockstudio/settings/editor/format_on_save` |
| `blockstudio/settings/blockEditor/disableLoading` | `blockstudio/settings/block_editor/disable_loading` |
| `blockstudio/settings/blockEditor/cssClasses` | `blockstudio/settings/block_editor/css_classes` |
| `blockstudio/settings/blockEditor/cssVariables` | `blockstudio/settings/block_editor/css_variables` |
| `blockstudio/settings/ai/enableContextGeneration` | `blockstudio/settings/ai/enable_context_generation` |

### Backward Compatibility

The old camelCase hook names are still supported for backward compatibility. Your existing code will continue to work without changes. However, we recommend migrating to the new snake_case names for consistency.

**Example migration:**

```php
// Before (v6)
add_filter('blockstudio/settings/blockEditor/cssClasses', function() {
    return ['my-stylesheet'];
});

// After (v7)
add_filter('blockstudio/settings/block_editor/css_classes', function() {
    return ['my-stylesheet'];
});
```

## Canonical Block Tags

Blockstudio 7.6 keeps project prefixes and exact aliases as runtime extension
points, but uses `<bs:namespace-slug>` as the canonical spelling in examples,
catalog output, render declarations, and diagnostics. Canonical tags carry the
real registered block name and do not depend on a host-specific filter.

For a project with `brand => ["theme-components"]` and `ui => ["bsui"]`:

```html
<!-- Legacy project shorthand -->
<brand-card>
  <ui-input />
</brand-card>

<!-- Canonical output -->
<bs:theme-components-card>
  <bs:bsui-input />
</bs:theme-components-card>
```

A standalone migration command inventories an existing project and rewrites
shorthands to the canonical spelling. It is report-first, blocks on unresolved
cases, and changes only tag names. See
[Block Tag Migration](/docs/dev/cli#block-tag-migration) for the command, its
inputs, and its safety behaviour.

## Asset File Naming

Blockstudio 7 introduces dot notation for asset file suffixes, replacing the old dash notation as the recommended convention.

### Changed File Names

| Old Name (v6) | New Name (v7) |
|---------------|---------------|
| `*-inline.(s)css` | `*.inline.(s)css` |
| `*-inline.js` | `*.inline.js` |
| `*-editor.(s)css` | `*.editor.(s)css` |
| `*-editor.js` | `*.editor.js` |
| `*-scoped.(s)css` | `*.scoped.(s)css` |
| `*-view.js` | `*.view.js` |

### Backward Compatibility

The old dash notation is still supported for backward compatibility. Your existing files will continue to work without renaming. However, we recommend migrating to dot notation for new blocks.

**Example migration:**

```
my-block/
├── block.json
├── index.php
├── style.css
├── style-inline.css   →  style.inline.css
├── style-scoped.css   →  style.scoped.css
├── style-editor.css   →  style.editor.css
├── script.js
├── script-inline.js   →  script.inline.js
├── script-editor.js   →  script.editor.js
└── script-view.js     →  script.view.js
```

## Field Switch

The `switch` property now defaults to `false` instead of `true`. In v6, every field had an invisible toggle on the left edge that was enabled by default. In v7, switch is opt-in and uses a visible eye icon in the field label.

### What Changed

- **Default is now `false`**: fields no longer have a switch unless you explicitly set `"switch": true`
- **Visible eye icon**: instead of a hidden left-side click zone, an eye icon button appears in the label area
- **Disabled overlay**: when a field is disabled, a blur overlay with "This field is disabled" text is shown instead of just reducing opacity

### Migration

If you relied on the default switch behavior in v6, you need to explicitly enable it:

```json
{
  "id": "title",
  "type": "text",
  "label": "Title",
  "switch": true
}
```

If you previously set `"switch": false` to disable the toggle, you can remove it since `false` is now the default.

## Tailwind CSS

Blockstudio 7 completely replaces the v6 Tailwind approach. In v6, Tailwind CSS was compiled client-side via the CDN in the editor and saved to disk on post save. In v7, Tailwind CSS is compiled server-side on every frontend request via [TailwindPHP](https://github.com/dnnsjsk/tailwindphp) with automatic file-based caching.

See the [Tailwind CSS documentation](/docs/tailwind) for full details on the new system.

### Always-On Server-Side Compilation

When `tailwind.enabled` is `true`, every frontend request is compiled server-side. The compilation flow:

1. WordPress renders the full page HTML into an output buffer
2. CSS class candidates are extracted from the HTML (fast regex, no compilation)
3. Candidates are sorted and hashed with the CSS config to create a cache key
4. On cache hit: the cached CSS file is read and injected
5. On cache miss: TailwindPHP compiles the CSS, writes it to Blockstudio's
   shared runtime cache under the `tailwind` scope, and injects it

The compiled CSS is injected as an inline `<style id="blockstudio-tailwind">` tag before `</head>`. This includes Tailwind's preflight and all matched utility classes.

The CDN script remains active in the editor for live preview only. It is never served on the frontend.

### `config` Format Changed

The `config` property changed from a JSON object (Tailwind v3) to a CSS string (Tailwind v4 CSS-first syntax).

**Before (v6):**

```json
{
  "tailwind": {
    "config": {
      "theme": {
        "extend": {
          "colors": {
            "primary": "pink"
          }
        }
      }
    }
  }
}
```

**After (v7):**

```json
{
  "tailwind": {
    "config": "@theme { --color-primary: pink; }"
  }
}
```

### `customClasses` Setting Removed

The `customClasses` array setting has been removed. With Tailwind v4's CSS-first approach, custom utility classes are defined directly in the `config` string using `@layer utilities`.

**Before (v6):**

```json
{
  "tailwind": {
    "customClasses": [
      { "className": "btn", "value": "px-4 py-2 rounded-lg font-medium" },
      { "className": "card", "value": "bg-white rounded-xl shadow-lg p-6" }
    ]
  }
}
```

**After (v7):**

```json
{
  "tailwind": {
    "config": "@layer utilities { .btn { @apply px-4 py-2 rounded-lg font-medium; } .card { @apply bg-white rounded-xl shadow-lg p-6; } }"
  }
}
```

Or via the filter for multiline configs:

```php
add_filter('blockstudio/settings/tailwind/config', function () {
    return <<<CSS
@layer utilities {
    .btn { @apply px-4 py-2 rounded-lg font-medium; }
    .card { @apply bg-white rounded-xl shadow-lg p-6; }
}
CSS;
});
```

The `blockstudio/settings/tailwind/custom_classes` filter has also been removed. Use the `blockstudio/tailwind/css` filter instead to append custom CSS rules.

### REST Endpoint Removed

The `POST /blockstudio/v1/editor/tailwind/save` endpoint has been removed. Compiled CSS is no longer saved from the editor. If you had custom code calling this endpoint, it can be safely removed.

### Caching

Blockstudio uses a candidate-based caching strategy. Rather than hashing the entire page HTML (which would bust the cache on every request due to nonces and timestamps), only the CSS class candidates are hashed. This means:

- Two pages with the same CSS classes share the same cached file
- Dynamic content (nonces, admin bars, timestamps) does not bust the cache
- The cache only invalidates when the set of CSS classes changes or the config changes

Cache files use the configured Blockstudio runtime root under
`sites/{network-blog}/{runtime-identity}/tailwind/`. Call
`Blockstudio\Runtime_Cache::purge('tailwind')` to force recompilation.

### Filter Changes

| Old Name (v6) | New Name (v7) |
|---------------|---------------|
| `blockstudio/tailwind/on_demand/css` | `blockstudio/tailwind/css` |
| `blockstudio/tailwind/assets/dir` | Removed |
| `blockstudio/settings/tailwind/custom_classes` | Removed |

### Removed Files and Enqueues

In v6, Tailwind CSS was enqueued as external stylesheets (`blockstudio-tailwind`, `blockstudio-tailwind-preflight`). In v7, all CSS is injected inline via an output buffer. There are no link tags or enqueued stylesheets for Tailwind on the frontend.

## Block Library

The built-in "Blockstudio Elements" library has been removed. The `library` setting in `blockstudio.json` and the `blockstudio/settings/library` filter no longer have any effect.

If you were using the library blocks (Gallery, Slider, Image Comparison, Code, Icon), copy the block folders from your v6 installation's `includes/library/blockstudio-element/` directory into your theme's blockstudio directory and update their `block.json` files with new names and categories.
