framer-code-components-overrides

Create Framer Code Components and Code Overrides. Use when building custom React components for Framer, writing Code Overrides (HOCs) to modify canvas elements, implementing property controls, working with Framer Motion animations, handling WebGL/shaders in Framer, or debugging Framer-specific issue

By fredm00n · 362 installs

npx skills add fredm00n/framerlabs --skill framer-code-components-overrides

Source repository · Upstream listing

Framer Code Development Section tags: [C] applies to code components, [O] to code overrides, [C/O] to both. Pitfalls (quick lookup) Issue Cause Fix Variable text not found in override Reading only props.children Check props.text first — variable bound text bypasses children Font styles not applying Accessing font props individually Spread entire font object: ...props.font Hydration mismatch Browser API in render Use isClient state pattern Dimensions stuck at 0 / SSR'd size persists Initial state read from window already equals real value, setState no ops Init state to 0, flip in effect (see [Hydration Safety]( hydration safety)) Color value crashes when user binds a token ControlType.Color returns {value: " xxx"} for tokens, string for static Unwrap with tok(v) before use (see [Color Tokens]( color tokens controltypecolor c)) Override props undefined Expecting property controls Overrides don't support addPropertyControls Override missing from Framer's picker dropdown Export value is produced by calling a factory/HOC generator — Framer's static scanner only recognizes literal override exports Write each override as a literal export function withX(Component) or export const withX = (Component) = … (see [Overrides Must Be Literal Exports]( overrides must be literal exports picker detection o)) Scroll animation broken overflow: scroll on container Use IntersectionObserver on viewport (see [Scroll Detection]( scroll detection constraint co)) Scroll/animation silently stops working when target ID is set useScroll target stored in useState captures null on first render Use useRef for live read targets (see [Live Read Refs]( live read refs useref not usestate co)) Named CMS layer not found by findByFramerName Layer is a dynamic component instance — name not on data framer name Wrap dynamic component in a plain frame carrying the expected name HLS video permanently pixelated .m3u8 in Chrome without HLS.js Use HLS.js dynamic import pattern (see [HLS Video Streaming]( hls video streaming m3u8 c)) Overlay stuck "half pressed" / needs two clicks to close Triggering Framer interactions with synthetic events ( dispatchEvent ) Call the React handler directly via fiber traversal (see [references/fiber handlers.md](references/fiber handlers.md)) Overlay stuck under content Stacking context from parent Use React Portal to render at document.body level Shader attach error Null shader from compilation failure Check createShader() return before attachShader() TypeScript Timeout errors Using NodeJS.Timeout type Use number instead — browser environment Component display name Need custom name in Framer UI Component.displayName = "Name" Easing feels same for all curves Not tracking initial distance Track initialDiff when target changes (see [references/patterns.md](references/patterns.md)) URL bound filters don't react to a programmatic URL write replaceState / pushState don't fire popstate Dispatch it manually after writing (see [Writing State into the URL]( writing state into the url c)) Slider drag floods browser history / traps Back pushState on every onChange Use replaceState for high frequency writes Range input shows blue native fill / unstyleable thumb Native <input type="range" chrome appearance:none + neutralise track + custom thumb per engine (see [Styling Native Range Inputs]( styling native range inputs c)) Contents [Foundations]( foundations) — components vs overrides, annotations, starter templates [Authoring]( authoring) — property controls, fonts, color tokens [Rendering & SSR]( rendering ssr) — hydration, canvas detection, concurrent rendering, npm imports [CMS]( cms) — text timing in overrides, code component CMS pattern [Overrides — specific patterns]( overrides specific patterns) — variant control, fiber handlers [DOM & Performance]( dom performance) — scroll detection, live read refs, portals, common patterns [Media]( media) — HLS video, WebGL [Debug]( debug) — gated logging Foundations Code Components vs Overrides Code Components [C] : Custom React components added to canvas. Support addPropertyControls . Code Overrides [O] : Higher order components wrapping existing canvas elements. Do NOT support addPropertyControls . Required Annotations [C/O] Always include at minimum: Full set: @framerDisableUnlink — Prevents unlinking when modified @framerIntrinsicWidth / @framerIntrinsicHeight — Default dimensions @framerSupportedLayoutWidth / @framerSupportedLayoutHeight — any , auto , fixed , any prefer fixed Code Override Pattern [O] Naming: Always use withFeatureName prefix. Overrides Must Be Literal Exports (picker detection) [O] Framer's override picker statically scans the file and only lists exports it can syntactically recognize as an override — a literal function declaration or an arrow assigned directly to the export. An export whose value is the return of a function call is invisible to the scanner: it won't appear in the Override dropdown (even though it would work if referenced by name). This bites hardest when you try to DRY up several near identical overrides with a factory: Both literal forms are recognized: export function withX(Component) {…} or export const withX = (Component) = (props) = … . The rule: never produce an override by calling a helper — repeat the literal per override, even if it's more verbose. (Full worked example — 3 setters + 1 reader sharing a store — in [references/patterns.md](references/patterns.md) → Shared State Between Overrides .) Code Component Pattern [C] Authoring Property Controls Reference [C] See [references/property controls.md](references/property controls.md) for complete control types and patterns. Font Handling [C/O] Never access font properties individually. Always spread the entire font object. Font control definition: Color Tokens ( ControlType.Color ) [C] A ControlType.Color value arrives as a plain string when the user picks a static color, but as a { value: " xxx" } object when bound to a Framer color token. Components that read the value directly break the moment the user binds a token. Always unwrap: Use tok() wherever a color prop is consumed for parsing, CSS strings, or canvas styles. Same wrapper shape may appear on other token bindable controls (sizes, shadows) — check before assuming. Rendering & SSR Hydration Safety [C/O] Framer pre renders on server. Browser APIs unavailable during SSR. Two phase rendering pattern: Never access directly at render time: window , document , navigator localStorage , sessionStorage window.innerWidth , window.innerHeight Initial state must match SSR, then flip in an effect: The initial state already equals the real value on the client, so setState becomes a no op and the SSR'd dimensions (always 0) persist forever in the rendered DOM. Pairing the 0 opacity gate with the flip in effect hides the first paint, otherwise you see a flash from 0/default → real size on refresh. Canvas vs Preview Detection [C/O] Use for: Debug overlays Disabling heavy effects in editor Preview toggles Concurrent Rendering: Wrap State Updates in startTransition [C/O] Framer runs on React's concurrent renderer. Multi setter updates in event handlers (steppers, async chains, form fields) can stutter under load. Wrap non urgent updates: Don't wrap the user input setter itself ( onChange → setValue ) — that one needs to feel immediate. NPM Package Imports [C/O] Standard import (preferred): Force specific version via CDN when Framer cache is stuck: Always include ?external=react,react dom for React components. CMS Content Timing in Overrides [O] CMS text arrives in props.text asynchronously (~50–200ms after hydration). For variable bound text from component props, it's synchronous on first render — no delay needed. The reliable pattern for both: use resolvePlainText(props) (see [Text in Overrides]( text in overrides o) below) and gate on the value being non empty: Avoid 100ms arbitrary delays — they cause race conditions when the element is already in the viewport on load. Text in Overrides [O] Text comes from two different sources depending on how it's set: Source Where it lives When Static text (typed in Framer) props.children nested structure Always available on first render Variable bound text (component prop / CMS) props.text (plain string) Available on first render for variables; async for CMS Always check props.text first, fall back to children: Never assume text is only in props.children . Variable bound text bypasses the children structure entirely — props.children will contain a placeholder while props.text has the real value. If you only read children, variable text is invisible to your override. CMS in Code Components [C] Code components consume a Framer CMS Collection List via a ControlType.ComponentInstance slot, then walk the resulting React element tree to extract per item content. Core helpers: useQueryData + getCollectionData to materialise items findByFramerName to extract named layers from each item's template Plain frames must wrap dynamic components if their name needs to be discoverable getPropertyControls(WrappedComponent) to inherit controls when one CMS component wraps another Full pattern, helper code, and traps: see [references/cms.md](references/cms.md). Overrides — Specific Patterns Variant Control [O] Cannot read variant names from props (may be hashed). Manage internally: Triggering Framer Attached Handlers [O] Synthetic DOM events ( dispatchEvent ) don't reliably trigger Framer Motion handlers — they leave the element in a half pressed state. Instead, walk the React fiber tree from the DOM node up to the handler bearing fiber and call it directly: Full helper, debugging snippets, deep link use case, and maintenance risks: see [references/fiber handlers.md](references/fiber handlers.md). DOM & Performance Scroll Detection Constraint [C/O] Framer's scroll detection uses viewport based IntersectionObserver. Applying overflow: scroll to containers breaks this detection. For scroll triggered animations, use: Live Read Refs: useRef , Not useState [C/O] Hooks that read .current live on every event (Framer Motion's useScroll , IntersectionObserver targets, RAF loops) must receive a useRef . Storing the target in useState captures null on the first hook call and never re subscribes once state flips. The trap is that this often appears to work — useScroll silently falls back to window scroll, so the page seems to animate at first glance until you pin the target with id="..." and everything freezes. Applies to any API that reads through a ref handle per event — not just useScroll . Z Index Stacking Context & React Portals [C/O] Problem: Components with position: absolute inherit their parent's stacking context. Even with z index: 9999 , they can't appear above elements outside the parent. Solution: Use React Portal to render at document.body level: Key differences: position: "fixed" positions relative to viewport, not parent Portal breaks out of component's DOM hierarchy and stacking context Works for modals, tooltips, popovers, loading overlays Canvas vs Published: Portals work in both canvas editor and published site. No RenderTarget check needed. Writing State into the URL [C] A component can drive Framer's native URL bound filtering by writing a query param. Framer's filters do