> Portal Navigation:
> 
> - Append `.md` to any URL under `https://dev.wix.com/docs/` to get its markdown version.
> - Pages are either content pages (article or reference text) or menu pages (a list of links to child pages).
> - To get a menu page, truncate any URL to a parent path and append `.md` (e.g. `https://dev.wix.com/docs/sdk.md`, `https://dev.wix.com/docs/sdk/core-modules.md`).
> - If a reference page seems to be missing its schema (parameters, return types, or type definitions), append `?schema=true` to its `.md` URL (e.g. `https://dev.wix.com/docs/contexts/contexts/stores/category-info/use-category-info-context.md?schema=true`).
> - Top-level index of all portals: https://dev.wix.com/docs/llms.txt
> - Full concatenated docs: https://dev.wix.com/docs/llms-full.txt
> - To build a Wix site agentically, follow https://www.wix.com/headless/skill.md

## Resource: Migrate a Service Plugin Extension

## Article: Migrate a Service Plugin Extension

## Article Link: https://dev.wix.com/docs/build-apps/develop-your-app/develop-an-app-with-the-cli/migrate-an-app-to-the-new-cli/migrate-an-app-from-the-legacy-cli/migrate-a-service-plugin-extension.md

## Article Content:

# Migrate a Service Plugin Extension

Add a service plugin extension to your new Wix CLI project as part of [migrating an app from the legacy Wix CLI](https://dev.wix.com/docs/build-apps/develop-your-app/develop-an-app-with-the-cli/migrate-an-app-to-the-new-cli/migrate-an-app-from-the-legacy-cli/migrate-a-legacy-cli-app-to-the-new-wix-cli.md).

## Folder structure

All service plugins follow the same pattern. The `<type>/` folder level is removed in the new structure, and the files take the plugin's name:

| Legacy path | New path |
|--------|-----|
| `src/backend/service-plugins/<type>/<plugin-name>/plugin.ts` | `src/extensions/backend/service-plugins/<plugin-name>/<plugin-name>.ts` |
| `src/backend/service-plugins/<type>/<plugin-name>/plugin.json` | `src/extensions/backend/service-plugins/<plugin-name>/<plugin-name>.extension.ts` |

> **Note:** `<plugin-name>` is your plugin's folder name in the legacy project. The new folder and files use the same name.

Because the folder is named after the plugin rather than its type, an app with more than one plugin of the same type keeps them in separate folders, just as it did before.

## Step 1 | Copy and rename the file

In the new project:

1. Create the folder `src/extensions/backend/service-plugins/<plugin-name>/`.
2. From the legacy project's `src/backend/service-plugins/<type>/<plugin-name>/` folder, copy `plugin.ts` into the new folder, and rename it to `<plugin-name>.ts`.

Don't copy the legacy `plugin.json` file. You recreate its values in `<plugin-name>.extension.ts`.

## Step 2 | Adapt the code to the new project

In `<plugin-name>.ts`:

1. Update any imports as needed, to use the new paths, including imports of backend code.
2. Add the SDK package the extension's code imports, if it isn't already in your project. The legacy CLI added it for you when it generated the extension: `@wix/ecom` for the Ecom types, `@wix/bookings` for the Bookings types, and `@wix/realtime` for the realtime permissions provider.

## Step 3 | Create the extension file

In the new project:

1. In `src/extensions/backend/service-plugins/<plugin-name>/`, create `<plugin-name>.extension.ts`.
2. Add the following code, and set each field to the value the table below specifies. Replace `<builderName>` with the builder for your extension's legacy type, which is the `extensions` function that defines this kind of extension. [Builder names and fields](#builder-names-and-fields) lists the builder for each type.

    ```ts
    import { extensions } from '@wix/custom-extensions';

    export default extensions.<builderName>({
      id: '<value>',
      name: '<value>',
      source: './extensions/backend/service-plugins/<plugin-name>/<plugin-name>.ts',
    });
    ```

    | Field | Source in legacy project | What to specify |
    |-------|--------------------------|-----------------|
    | `id` | `id` in `plugin.json` | Copy source as is |
    | `name` | `name` in `plugin.json` | Copy source as is |
    | `source` | None | Path to `<plugin-name>.ts`, relative to `src/` |

3. If your legacy `plugin.json` sets additional fields for the extension's type, add them inside the same object. [Builder names and fields](#builder-names-and-fields) lists the additional fields each type takes, and [Example with optional fields](#example-with-optional-fields) shows where they go. For example, an Ecom validations plugin takes `validateInCart`, and omitting it stops the plugin from validating the cart.

<blockquote class="important">

__Important:__
The `id` must match the value from the legacy `plugin.json`. Otherwise, the new entry is treated as a separate extension instead of a continuation of the legacy one.

</blockquote>

### Builder names and fields

| Legacy type | Builder | Additional fields |
|-------------|---------|-------------------|
| `ecom-shipping-rates` | `ecomShippingRates` | Optional: `description`, `fallbackDefinitionMandatory`, `learnMoreUrl`, `dashboardUrl`, `thumbnailUrl` |
| `gift-cards-provider` | `ecomGiftCards` | None |
| `ecom-discounts-trigger` | `ecomDiscountTriggers` | None |
| `ecom-payment-settings` | `ecomPaymentSettings` | Optional: `fallbackValueForRequires3dSecure` |
| `ecom-validations` | `ecomValidations` | Optional: `validateInCart` |
| `ecom-additional-fees` | `ecomAdditionalFees` | None |
| `staff-sorting-provider` | `bookingsStaffSortingProvider` | Required: `methodName`, `methodDescription`. Optional: `dashboardPluginId` |
| `bookings-pricing-provider` | `bookingsPricingProvider` | Optional: `pricingProviderName` |
| `realtime-permissions-provider` | `realtimePermissionsProvider` | Optional: `providerName` |

> **Note:** Four legacy service plugin types have no builder in either structure: `ecom-recommendations-provider`, `seo-keywords-suggestions`, `premium-custom-charges`, and `external-database-provider`. The legacy CLI doesn't generate them, so a project has one only if an earlier version of the legacy CLI generated it. If yours does, check with Wix before migrating it, since the new structure has nothing to migrate it to.

### Example with optional fields

```ts
import { extensions } from '@wix/custom-extensions';

export default extensions.ecomShippingRates({
  id: '<value>',
  name: '<value>',
  description: '<value>',
  fallbackDefinitionMandatory: false,
  learnMoreUrl: '<value>',
  dashboardUrl: '<value>',
  thumbnailUrl: '<value>',
  source: './extensions/backend/service-plugins/<plugin-name>/<plugin-name>.ts',
});
```

## Step 4 | Register the extension

In the new project, in `src/extensions.ts`:

1. Import the extension:

    ```ts
    import myServicePlugin from './extensions/backend/service-plugins/<plugin-name>/<plugin-name>.extension';
    ```

2. Add a `.use()` call for it to the `app()` chain, on its own line:

    ```ts
    .use(myServicePlugin)
    ```

## Step 5 | Return to the main migration guide

Return to [Install the extension's dependencies](https://dev.wix.com/docs/build-apps/develop-your-app/develop-an-app-with-the-cli/migrate-an-app-to-the-new-cli/migrate-an-app-from-the-legacy-cli/migrate-a-legacy-cli-app-to-the-new-wix-cli.md#install-the-extensions-dependencies) in the main migration guide.