Marketplace

Submitting a module or theme

So you've built something for Rhapsody and you'd like other people to use it — nice. This guide walks through everything from "what actually gets submitted" down to filling in each field on the form, so you're not guessing. It's long, but you don't need to read it front to back: skim the headings and jump to whatever you're stuck on.

The big idea: you're not uploading code

This is the one thing worth understanding before anything else, because it shapes every field on the submission form. Submitting to the marketplace means listing a package you've already published — it doesn't mean uploading a zip file of your code for us to host. You publish your module or theme as a normal Composer package first (on Packagist, or a Git host Composer can reach), and the marketplace listing is really just a storefront page pointing at it: a name, a description, a category, screenshots, and a link to the real package.

Why bother mentioning this? Two reasons. First, it explains why package_name and repository_url are required fields and there's no file upload for your actual code anywhere on the form — that's not a missing feature, it's the whole design. Second, it means the thing you're really submitting for review is a public package, so reviewers (and eventually, buyers) need to be able to actually reach it. A private repo with no public access, or a package name that doesn't correspond to anything installable, is the single most common reason a submission stalls.

Before you start: a quick checklist

Have these ready and the form takes about five minutes. Skip them and you'll be back here anyway when a field doesn't make sense.

  • Your package is published and publicly reachable — ideally on Packagist, but any Composer-installable public repo works.
  • It has a LICENSE file. "MIT" is the friendliest default if you don't have a strong preference.
  • The package name follows Composer's vendor/package-name format — all lowercase, hyphens not underscores.
  • There's a real README with install/usage instructions — not because the marketplace reads it, but because reviewers and buyers will.
  • If it's a module: a working module.json manifest with your actual permissions declared. See the modules documentation for the full schema — this guide won't repeat it verbatim, since that page is the source of truth and this one would just go stale next to it.
  • If it's a theme: a handful of real screenshots ready to go. See the screenshots section below for sizing.

The three tiers, and how you move between them

Every marketplace listing sits at one of three trust levels:

Rhapsody Official

Built and maintained by the core team. Not something you self-assign; it's reserved for what the framework authors ship directly.

Verified

Passed a full manual review. This is what your listing gets promoted to once someone's actually looked at it.

Community

Where every new submission starts. It means "cleared basic automated checks, waiting on a human."

In practice: you submit, it lands as Community, and it stays there until it's reviewed. There's no fast-track or paid upgrade path — Verified only happens through the same review queue everything goes through.

Filling in the form, field by field

Module or Theme

This changes more than it looks like it does. Pick Theme and the category field disappears entirely — themes are automatically filed under the Theme category server-side, regardless of what you'd have picked otherwise, so there's nothing to configure there.

Category

Modules only. Pick whichever fits best — reviewers can recategorize if you're off, so don't agonize over edge cases:

  • Security auth, firewalls, access control
  • SEO sitemaps, meta tags, structured data
  • CMS content blocks, page builders, drafts
  • Commerce checkout, carts, order management
  • Analytics visitor insights, event tracking
  • Forms multi-step forms, validation
  • Media galleries, video, image tooling
  • Performance caching, CDN, asset optimization
  • Integrations connecting Rhapsody to other services
  • Utilities backups, scheduling, dev tools

Composer package name

The real, published package name — exactly what someone would type after composer require. Format is vendor/package-name:

vendor/package-name       # good
my_cool_module            # missing the vendor/ prefix
Vendor/PackageName        # Composer names are lowercase

This has to be unique across the whole marketplace — if someone's already listed this exact package, the form will tell you rather than let you create a duplicate.

Repository URL

A link to the actual source — GitHub, GitLab, wherever. This needs to be publicly viewable; it's the first thing a reviewer opens, and it's also what curious buyers click before they trust a paid listing enough to buy it.

Documentation URL (optional)

Only fill this in if you have docs living somewhere separate from your README — a dedicated docs site, a wiki, that sort of thing. If your README already covers usage, skip this; there's no need to duplicate a link to the same repo you already gave above.

Short description

One line, 280 characters max, shown on every listing card across the catalog. This is doing a lot of work in very little space, so lead with what it does, not what it is:

Good: "Two-factor authentication and brute-force throttling for Rhapsody logins."
Less good: "A great module for authentication and security."

The first tells someone scanning a category page whether to click. The second doesn't.

Full description (optional)

Shown on the item's own detail page. One formatting detail that matters: separate paragraphs with a genuinely blank line. The display template splits on double line breaks to build separate <p> tags — a single line break between sentences will just get mashed into one paragraph.

License

Whatever your repo's LICENSE file actually says — MIT, GPL-3.0, proprietary, etc. This should match reality, since it's what buyers are legally relying on.

Minimum Rhapsody version (optional)

A Composer-style constraint for the oldest framework version you've actually tested against:

^1.0    # 1.0 and any later 1.x release
^1.2    # be specific if you rely on something added in 1.2

Tags (optional)

Comma-separated, and worth doing properly — tags are how someone finds your item by what it does rather than by category alone. Aim for specific, not decorative:

Good:  two-factor, oauth, session, rate-limiting
Less useful: security, module, rhapsody

The category already says "security" and "module" — tags should add information the category can't.

Pricing

Free by default. Uncheck "This item is free" to set a price and choose one-time or subscription billing.

Heads up

One honest caveat worth knowing up front: checkout isn't fully wired up yet. Paid listings work end-to-end for browsing and display, but the actual payment flow is still being built — so pricing a listing today gets it correctly marked and displayed as paid, just without a live way for anyone to complete a purchase yet. That's coming; it's not something you need to work around, just something to expect for now.

Screenshots (optional)

This is genuinely different depending on what you're submitting:

  • Themes should have several — enough to show off the range of what it looks like (a homepage, an inner page, mobile if it's notably different). The gallery on a theme's detail page is built for this; a theme with zero screenshots is the one case where the page shows an explicit "none added yet" placeholder, so it's worth not skipping.
  • Modules usually need few or none at all — a module that adds two-factor auth doesn't have much to screenshot. If there's a genuinely visual piece (an admin settings screen, say), include it; otherwise don't force it.

Technical specifics: JPEG, PNG, or WebP, up to 5MB each. For themes specifically, 16:9 aspect ratio is worth aiming for — that's what the gallery thumbnails are cropped to, so a screenshot shot in a wildly different ratio will get cropped in ways you didn't choose.

What happens after you submit

Your listing saves immediately as Community tier, status "pending review," and then sits in a queue reviewed oldest-first. There's no fixed turnaround time promised — it's a real human looking at a real submission, not an automated approval. Once it's approved, it goes live in the catalog as Verified tier. If it's rejected, there's no automated reason sent back yet either — if that happens and you're not sure why, just reach out directly.

A note for module authors

Everything about permissions, the five sandboxed facades, and what a compliant module.json actually looks like lives in the modules documentation — that's the authoritative reference, so this guide intentionally doesn't try to restate the schema here. The short version, if you haven't read it yet: modules declare what they need up front (events, routes, Twig functions, storage, settings) rather than reaching for the container or raw database access directly, and that manifest is exactly what a reviewer reads first.

A note for theme authors

Two things worth knowing that aren't obvious from the theming docs alone:

  • If your theme ships its own login.twig/register.twig, make sure they extend your own layouts/main.twig — not @core/layouts/main.twig. It's an easy copy-paste mistake from the default theme's versions, and the symptom is subtle: your theme's navbar and styling quietly get replaced by core's on just those two pages, even though every other page looks right.
  • Follow the documented directory structure (layouts/, home/, pages/, errors/) even for pages you think are optional. The theme resolution order falls back to the default theme for anything missing, so a gap doesn't break the site — but it does mean part of your theme quietly isn't your theme on whichever page you skipped.

Frequently asked

Can I edit my listing after it's submitted?

Not through a self-serve form yet — for now, reach out directly if something needs correcting.

My package is on GitHub but not Packagist — is that okay?

Yes, as long as it's genuinely Composer-installable (a proper composer.json at the root). A real Packagist listing is the simplest path, but it's not required.

Does submitting cost anything?

No. The pricing field is what buyers pay for your item — submitting itself is always free.

Can I submit something closed-source or paid-only?

Yes — that's exactly what the pricing field and a private, purchase-gated repository are for (see the honest caveat on checkout above).

More questions? See the full marketplace FAQ.