What Framer's Marketplace review actually checks
Most component rejections come from the same handful of technical rules, and none of them are about design. Here is what reviewers look for, from someone who has been through it repeatedly.
If you are submitting components to the Framer Marketplace, the rejections that hurt are the technical ones — the review comes back, you read it twice, and you still are not sure what to change. Almost all of them fall into the same small set of rules, and none are about how the thing looks.
Here is what actually gets checked, and how to satisfy each one before you submit.
Animation has to stop when nobody is watching
A component that runs a requestAnimationFrame loop must pause when it scrolls out of the viewport. An always-on loop is the single most common rejection reason, because a page with three of them never gets an idle frame.
The fix is an IntersectionObserver scoped to the component's own element: cancel the loop when it leaves, restart when it returns. Do this before you submit, not after the rejection — it is a ten-minute change that is easy to forget on every component you have already written.
It has to render without a browser
Framer renders your component on the canvas and again when exporting thumbnails, in an environment with no live animation. A component that assumes a browser will either fail there or produce an empty box.
Gate the animation behind a static-renderer check and return a still fallback in that case. That fallback matters more than it sounds: it is what shows on the canvas while a designer is deciding whether to use your component, and what appears in previews.
No external runtime dependencies
Your component cannot fetch its libraries from a CDN at runtime. If it depends on a shader or animation library, that code has to be vendored into the file itself rather than imported from an external host.
This one catches people who developed against a bare package import locally and never checked what the published bundle actually requests.
Stay inside your own subtree
A component may not assign IDs or attributes to nodes outside itself, and it may not attach observers to the document body. Both look harmless in a demo and both break unpredictably once someone drops two copies of your component on one page.
If you need to observe something, scope the observer to an element you own and walk from there. If you need to find headings elsewhere on the page, take an explicit scope from a property control rather than assuming the whole document is yours.
Sensors need permission, from a gesture
Anything touching device orientation, motion or similar APIs needs an explicit consent action — a button the visitor presses — and the permission request has to happen inside that gesture. Auto-starting a sensor on mount will not pass, and on most browsers it would not work anyway.
Submit with this checklist
Before you send anything: does the loop pause off screen, does it render statically, are all dependencies inlined, does it touch only its own subtree, and does any sensor sit behind a button? Five questions. They cover the overwhelming majority of technical rejections, and working through them takes far less time than one review cycle.