Override Examples

There are a few common use cases for Overrides, below you’ll find examples on how to implement them. The code will vary slightly in your specific usage.

Custom IDs and Attributes

You can also use overrides to add custom IDs and data attributes to elements. For example if you want to add a data-xx or id tag to elements.

import type { ComponentType } from "react";

export function withTags(Component): ComponentType {
    return (props) => {
        return <Component {...props} id="SomeID" data-framer="5678" />
    }
}

We don’t recommend to override core attributes like class or className as Framer relies on those and it will result in breaking styling. If you must, we recommend concatenating with the existing class value.

Click Tracking

A popular use-case for Overrides is click tracking, you can do this quite simply. This depends on your tracking setup, but generally includes a call to a tracking API on click. Another way to do tracking is to add a data attribute to the layer (see above example) and adding a head script to your page in the Custom Code that performs the tracking.

import type { ComponentType } from "react";

export function withButtonTracking(Component): ComponentType {
    return (props) => {
      
        const handleClick = () => {
          // Call to tracking API
          void fetch("api.example.com/tracking/button")

          // Call normal onClick event if exists
          props?.onClick() 
        }
      
        return <Component {...props} onClick={handleClick} />
    }
}

Text Content

Sometimes you want to dynamically replace text contents for any text element. You can use the text property to pass in any text content. The preview or published site will now show “Hello World”. However in many cases you can use Fetch for this instead.

import type { ComponentType } from "react";

export function withText(Component): ComponentType {
    return (props) => {
        return <Component {...props} text="Hello World" />
    }
}

Application State

Application state refers to the data flow within your app, specifically how elements communicate with each other. This example has two Overrides to connect a button to a counter. Create an Override file with the following code and set up a similar layout. Then, connect the two overrides: attach withIncrement to the button and withCount to the text field of the counter. Please note that if you want to build a "real app" that creates, updates, and lists dynamic data, consider using a simple React application or a no-code app builder if you don't know how to code.

import type { ComponentType } from "react"
import { createStore } from "https://framer.com/m/framer/store.js@^1.0.0"

const useStore = createStore({ count: 0 })

export const withCount = (Component): ComponentType => {
    return (props) => {
        const [store, setStore] = useStore()
        return <Component {...props} text={`${store.count}`} />
    }
}

export const withIncrement = (Component): ComponentType => {
    return (props) => {
        const [store, setStore] = useStore()
        const onTap = () => setStore({ count: store.count + 1 })
        return <Component {...props} onTap={onTap} />
    }
}