Setup
This guide explains how to prepare a module for distribution through plentyMarketplace. A module that's published and distributed this way is called an extension (see Introduction), and needs two things beyond a regular module: an extension.config.ts so its own code can gate itself (see Gates), and a marketplace.json plus a meta/ folder so it can be listed on the marketplace at all. packages/module-four-seasons is a working reference for all of it.
Before you start
Before you set up an extension, ensure you have:
- A working Nuxt module, built following the regular Modules guides.
- A
package.jsonat the root of that module.
Keep the name identifier consistent
Your extension's name ends up written in three places: package.json, extension.config.ts, and your module's own meta.name. Keep all three identical — the same scoped string, e.g. @plentymarkets/four-seasons — so there's never any ambiguity about which package, config, and registered Nuxt module belong to the same extension.
Declare the name in
package.json:json// my-module/package.json { "name": "@plentymarkets/four-seasons" }Create
extension.config.tsinside your module'sruntime/folder, next to itsplugins/,composables/, andcomponents/, and declare the same name withdefineExtensionConfig:ts// my-module/runtime/extension.config.ts import { defineExtensionConfig } from '#imports'; export default defineExtensionConfig({ name: '@plentymarkets/four-seasons', });This is the identifier PlentyONE licenses the extension under and returns from the backend's extensions list, so it has to match
package.json'snameexactly. Every other file in your module imports this one config object rather than repeating the string.Give your module's own Nuxt entry point the same name, on
meta.name:ts// my-module/src/module.mts import { defineNuxtModule } from '@nuxt/kit'; export default defineNuxtModule({ meta: { name: '@plentymarkets/four-seasons', }, // ... });
Describe the extension for the marketplace listing
Add a
marketplace.jsonat the root of your module:json{ "marketplaceName": { "en": "Four Seasons", "de": "Vier Jahreszeiten" }, "price": 0.0, "shortDescription": { "en": "Adds an animated falling leaves, snow, or petal overlay to every shop page.", "de": "Fügt jeder Shop-Seite eine animierte Überlagerung aus fallenden Blättern, Schnee oder Blütenblättern hinzu." }, "categories": ["4408"], "keywords": ["seasonal", "animation"] }Field Required Notes marketplaceNameyes Localized object with non-empty enanddestrings, no other langs.shortDescriptionyes Same localized shape as marketplaceName.priceyes A float written with a decimal point ( 0.0, not0). Must be0.0(free) or at least10.0(paid). Anything in between is rejected.categoriesyes Must be ["4408"]. Other categories may become available in the future.subscriptionno Array of objects, one per billing option. See Offer a subscription. keywordsno Array, if present. There's no identity field here — the module's identity for licensing still comes entirely from
package.json'sname.
Add the required meta assets
Create a
meta/folder with icons, preview images, and documents:my-module/ meta/ images/ icon_author_xs.png # 32x32 icon_author_sm.png # 256x256 icon_author_md.png # 512x512 icon_plugin_xs.png # 32px wide, height <= 32 icon_plugin_sm.png # 256px wide, height <= 256 icon_plugin_md.png # 512px wide, height <= 512 preview_0.png # 1-7 preview_<n>.png files, each a PNG under 1 MB documents/ changelog_en.md changelog_de.md support_contact_en.md # must include a support email address support_contact_de.md user_guide_en.md user_guide_de.mdThe author icons must be exactly square at each fixed size; the plugin icons share the same fixed width but may be shorter than the given height. Every document must exist and be non-empty, and the English support contact file must contain an email address.
List both
marketplace.jsonandmetain your module'spackage.jsonfilesarray so they're included when the package is published.
Offer a subscription
Besides a one-time purchase, you can offer your extension as a subscription. Add a subscription array to marketplace.json with one entry per billing option, and remove the options you don't want to offer (for example, to offer monthly billing only). Set the top-level price to 0.0 for the base extension.
{
"price": 0.0,
"subscription": [
{ "interval": "monthly", "price": 10.0 },
{ "interval": "quarterly", "price": 30.0 },
{ "interval": "half-yearly", "price": 60.0 },
{ "interval": "yearly", "price": 120.0 }
]
}| Field | Description |
|---|---|
interval | Billing interval: monthly, quarterly, half-yearly, or yearly. |
price | Price per interval in euros. The PlentyONE docs state that only values above 10.00 are valid. |
A free trial gives users the full functionality of the extension for 30 days, once per user. Afterwards they must buy or subscribe to keep using it.
Next step
Once the files are in place, publish the extension.
See also
- Introduction — what an extension is and when this setup applies.
- Publishing — validate and publish the extension to the marketplace.
- Gates — gate your code with the
extension.config.tsyou just created. - packages/module-four-seasons — a working reference implementation.