fredm00n/framerlabs7 files

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 issues like hydration errors and font handling.

Specification
Skill ID
fredm00n/framerlabs/framer-code-components-overrides
Publisher
fredm00n
Repository
framerlabs
Installs
0
Files
7
Synced
Sep 23, 2026
How to use it

Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.

fredm00n/framerlabs/framer-code-components-overridesInstalls these files
  • SKILL.md
  • references/cms.md
  • references/fiber-handlers.md
  • references/hls-video.md
  • references/patterns.md
  • references/property-controls.md
  • references/webgl-shaders.md

What this skill tells the agent

Framer Code Development

Section tags: [C] applies to code components, [O] to code overrides, [C/O] to both.

Pitfalls (quick lookup)

IssueCauseFix
Variable text not found in overrideReading only props.childrenCheck props.text first — variable-bound text bypasses children
Font styles not applyingAccessing font props individuallySpread entire font object: ...props.font
Hydration mismatchBrowser API in renderUse isClient state pattern
Dimensions stuck at 0 / SSR'd size persistsInitial state read from window already equals real value, setState no-opsInit state to 0, flip in effect (see Hydration Safety)
Color value crashes when user binds a tokenControlType.Color returns {value: "#xxx"} for tokens, string for staticUnwrap with tok(v) before use (see Color Tokens)
Override props undefinedExpecting property controlsOverrides don't support addPropertyControls
Override missing from Framer's picker dropdownExport value is produced by calling a factory/HOC-generator — Framer's static scanner only recognizes literal override exportsWrite each override as a literal export function withX(Component) or export const withX = (Component) => … (see Overrides Must Be Literal Exports)
Scroll animation brokenoverflow: scroll on containerUse IntersectionObserver on viewport (see Scroll Detection)
Scroll/animation silently stops working when target ID is setuseScroll target stored in useState captures null on first renderUse useRef for live-read targets (see Live-Read Refs)
Named CMS layer not found by findByFramerNameLayer is a dynamic component instance — name not on data-framer-nameWrap dynamic component in a plain frame carrying the expected name
HLS video permanently pixelated.m3u8 in Chrome without HLS.jsUse HLS.js dynamic import pattern (see HLS Video Streaming)
Overlay stuck "half-pressed" / needs two clicks to closeTriggering Framer interactions with synthetic events (dispatchEvent)Call the React handler directly via fiber traversal (see references/fiber-handlers.md)
Overlay stuck under contentStacking context from parentUse React Portal to render at document.body level
Shader attach errorNull shader from compilation failureCheck createShader() return before attachShader()
TypeScript Timeout errorsUsing NodeJS.Timeout typeUse number instead — browser environment
Component display nameNeed custom name in Framer UIComponent.displayName = "Name"
Easing feels same for all curvesNot tracking initial distanceTrack initialDiff when target changes (see references/patterns.md)
URL-bound filters don't react to a programmatic URL writereplaceState/pushState don't fire popstateDispatch it manually after writing (see Writing State into the URL)
Slider drag floods browser history / traps BackpushState on every onChangeUse replaceState for high-frequency writes
Range input shows blue native fill / unstyleable thumbNative <input type="range"> chromeappearance:none + neutralise track + custom thumb per engine (see Styling Native Range Inputs)

Contents

  • Foundations — components vs overrides, annotations, starter templates
  • Authoring — property controls, fonts, color tokens
  • Rendering & SSR — hydration, canvas detection, concurrent rendering, npm imports
  • CMS — text timing in overrides, code-component CMS pattern
  • Overrides — specific patterns — variant control, fiber handlers
  • DOM & Performance — scroll detection, live-read refs, portals, common patterns
  • Media — HLS video, WebGL
  • 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:

/**
 * @framerDisableUnlink
 * @framerIntrinsicWidth 100
 * @framerIntrinsicHeight 100
 */

Full set:

  • @framerDisableUnlink — Prevents unlinking when modified
  • @framerIntrinsicWidth / @framerIntrinsicHeight — Default dimensions
  • @framerSupportedLayoutWidth / @framerSupportedLayoutHeight — any, auto, fixed, any-prefer-fixed

Code Override Pattern [O]

import type { ComponentType } from "react"
import { useState, useEffect } from "react"

/**
 * @framerDisableUnlink
 */
export function withFeatureName(Component): ComponentType {
    return (props) => {
        // State and logic here
        return <Component {...props} />
    }
}

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:

// ❌ BROKEN — factory hides the overrides from the picker.
// Only literal functions in the file get listed; these three never appear.
const setVariant = (name) => (Component) => (props) => {
    const [, setStore] = useStore()
    return <Component {...props} onClick={() => setStore({ variant: name })} />
}
export const withSetVariant1 = setVariant("Variant 1") // not listed
export const withSetVariant2 = setVariant("Variant 2") // not listed
export const withSetVariant3 = setVariant("Variant 3") // not listed

// ✅ CORRECT — each override is a literal function; all are listed.
export function withSetVariant1(Component): ComponentType {
    return (props) => {
        const [, setStore] = useStore()
        return <Component {...props} onClick={() => setStore({ variant: "Variant 1" })} />
    }
}

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 → Shared State Between Overrides.)

Code Component Pattern [C]

import { motion } from "framer-motion"
import { addPropertyControls, ControlType } from "framer"

/**
 * @framerDisableUnlink
 * @framerIntrinsicWidth 300
 * @framerIntrinsicHeight 200
 */
export default function MyComponent(props) {
    const { style } = props
    return <motion.div style={{ ...style }}>{/* content */}</motion.div>
}

MyComponent.defaultProps = {
    // Always define defaults
}

addPropertyControls(MyComponent, {
    // Controls here
})

Authoring

Property Controls Reference [C]

See 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.

// ❌ BROKEN - Will not work
style={{
    fontFamily: props.font.fontFamily,

Use this skill in a project

Open any RiverX project, search the Skills panel for fredm00n/framerlabs/framer-code-components-overrides, and install it in one click.

Use this skill