Handshake
Use your Framer components in your React code.
This feature is powered by advanced technologies and is being actively worked on. Please help us make it even better by sharing any feedback or reporting any bugs you may find in our Discord channel.
Note: During the Beta period we only support importing components into the recommended environments below (Next.js and CodeSandbox, with more coming soon)
#Getting Started
#Copy Import
The first step is to get an import statement for your Smart Component.
Double click your component on the canvas or in the component list to open it, then click the the Handshake button in the top right corner. This will open a Handshake modal with an example of how to use the component and a button to copy its import or only its URL. Go ahead and click on Copy Import.
Handshake Modal
Tip: Right-click to copy
You can right-click components on the canvas and select Copy › Copy Import or right click any component in the assets panel and select Copy Import.
#Paste Import
In your React environment, open a file where you'd like to import your component, then paste your import statement at the top along with your other imports. This is bringing the latest version of your component in directly from Framer.
import React from "react"import Library from "other-libraries"import Card from "https://framer.com/m/Card-abcd.js@abcdef1234"
#Insert Component
Now all you need to do is add the component to your JSX.
import Card from "https://framer.com/m/Card-abcd.js@abcdef1234"
function Page() { return ( <div> <Card /> </div> )}
Voila! Your Smart Component is now living within your codebase and can be interacted with like any other content.
#Updating Components
To import the latest version of your component, make your changes in Framer then copy a new import using the Copy Import button. This will automatically give you an Import that points to the latest version of your component.
https://framer.com/m/Toggle-lEdS.js@iDfYSsKU0zyuqe77NcBi
To understand what is happening here: the last part of the URL (after @
) is known as the Save ID. This locks your URL import to the exact version of your component at the time you copied the link. These versioned links are stable forever, and ensure your component never changes unexpectedly.
In some cases like quick prototyping, you may want to fetch the latest version of the component on every your load your page, to do that you can remove the Save ID like so:
https://framer.com/m/Toggle-lEdS.js
#Environments
#Next.js
There are a few things you’ll want to set up in your Next.js environment to ensure everything works smoothly.
Starting from scratch? Clone this repo or download a zip to get started.
Ensure you have installed the latest beta versions of the next
, framer
, and framer-motion
dependencies.
yarn add next framer framer-motion
npm install next framer framer-motion
Then you'll need to enable the urlImports
Next.js experiment inside next.config.js
to support URL Imports.
Within the urlImports
field, you'll need to list all allowed URL prefixes. Below is a config list that will get you started for most Handshake use-cases.
module.exports = { experimental: { urlImports: [ "https://framer.com/m/", "https://framerusercontent.com/", "https://ga.jspm.io/", "https://jspm.dev/", ], },}
That is it! You can now follow the getting started steps above.
#CodeSandbox
Use the ES Modules template to try out Handshake on CodeSandbox.
#Miscellaneous
#Webpack lock files
In order to produce safe, reproducible builds remotely—the Webpack team added caching & lockfiles for all URL imports used in Next.js and Webpack 5.
These look like two files and two folders:
// Filesclient.webpack.lockserver.webpack.lock
// Foldersclient.webpack.lock.data server.webpack.lock.data
These files should be checked-into your git repository so remote builds don’t have to fetch each URL during each build—this will also help if any CDN were to go down temporarily during a build.
Tip: Mark as generated
To let GitHub know that you didn’t actually type all these cache files as part of your PRs, you can mark them as generated files via a .gitattributes
file with the contents of:
client.webpack.lock.data linguist-generated=trueserver.webpack.lock.data linguist-generated=true
#Fonts
To use fonts with Handshake components, you’ll need to provide them yourself from your website. Whether they're Google Fonts or custom ones, you'll just need to import them as usual: using <link>
or @import
for Google Fonts, @font-face
for custom ones.
For custom fonts, you’ll want to make sure the font-family
name is the exact same name as the font you used in Framer.
Tip: Font Names in Framer
Sometimes custom fonts in Framer may be named something like GT Walsheim Medium. In that case you can add a second @font-face
rule with the same URLs but a different name. This will “overload” your font names and allow them to work both across your website and in your imported components.
#TypeScript
TypeScript doesn’t like URL imports just yet, so if you want to silence the errors you’ll need a declaration.d.ts
file with the following contents. This file should be auto-generated when installing `framer`.
declare module "https://framer.com/m/*";
This will make TypeScript ignore types for Framer URLs.
#Troubleshooting
Something going wrong? Here’s a few common errors and how to fix them.
Avoiding Errors
Since we're using the latest technologies for Handshake, the best thing to ensure a smooth experience is to make sure all the components in your Framer project are up to date. Double check each of the components in your Assets panel for an "Update" button. If there is no update button, you're good to go.
Sometimes there may be an out of date component within one of the components you are using, if you are the owner of that component you can use the "View Primary" action within the context menu to visit the source project of the component and ensure all components are up to date there.
AllowedUris Policy
Since next@11.1.3-canary.92
you need to add add all allowed URL prefixes inside your next.config.js
file. Seeing the error of "https://example.com/modules/12345 does not match allowedUris policy" means you'll need to add the URL prefix to your allow list like so:
module.exports = { experimental: { urlImports: ['https://example.com/modules/'], },}
Older Next.js Versions
If you recently updated your dependencies or find your URL imports are not working correctly anymore, your Next.js config may not match the proper API for that version. If you're Next.js version is next@11.1.3-canary.90
or earlier you may have a next.config.js
that looks like this:
module.exports = { webpack: (config) => { config.experiments = config.experiments || {}; config.experiments.buildHttp = true; return config; },};
This is correct for early canary versions of next@11.1.3
however you'll now want to make sure to update your Next.js to the latest canary version and update your config file using the Next.js setup steps above.
Cannot find module
Type error: Cannot find module 'https://framer.com/…' or its corresponding type declarations.
TypeScript doesn’t like URL imports just yet, learn more about how to make them work.
Global Framer and React
window.Framer is not defined
window.React is not defined
Cannot destructure useState of c as it is undefined
For errors such as these, it generally means the components are “old”. To fix them, you should make sure all your components are up to date. Then you’ll also want to make sure to regenerate all smart components within your component. If that still doesn't work, please message Framer support.
Deprecated Packages
Packages will not work in Handshake components. If there is a package out there that currently isn’t fulfilled by our default components, please let us know so we can add it.
ECONNRESET
Sometimes when loading modules for the first time, some URL imports will trigger an error. In most cases refreshing the page will fix it.
Module not found: read ECONNRESET