Framer's custom code settings let you inject anything into your site's head or body — analytics scripts, chat widgets, CSS overrides, marketing pixels, custom fonts, or any third-party tool that provides a script tag or embed code. This is AURA's integration layer for everything not natively supported in Framer's UI.
Accessing custom code settings
Click the globe icon in the Framer toolbar → Site Settings → scroll to Custom Code. You'll see two fields: Head and Body (End). There is also a page-level custom code option in each page's Page Settings for code that should only run on a specific page.
Head vs Body (End) — when to use each
Head loads before the page renders. Use it for: analytics scripts, consent banners, font preloads, and any script that needs to be present before content paints. Body (End) loads after the page content. Use it for: chat widgets, support tools, marketing pixels, and any script where a slight delay is acceptable. When in doubt, use Body (End) — scripts in Head that block rendering will hurt your page load score.
Example: adding a custom font preload
If you're loading a self-hosted font or preloading a Google Font for performance, add this to Head:
<link
rel="preload"
href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@300;400&display=swap"
as="style"
/>
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@300;400&display=swap"
/>
<link
rel="preload"
href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@300;400&display=swap"
as="style"
/>
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@300;400&display=swap"
/>
<link
rel="preload"
href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@300;400&display=swap"
as="style"
/>
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@300;400&display=swap"
/>
Example: global CSS override
To adjust styles that Framer's UI doesn't expose — like the scrollbar, text selection color, or focus ring — add a style block to Head:
<style>
::-webkit-scrollbar {
width: 6px;
}
::-webkit-scrollbar-track {
background: #0e0b09;
}
::-webkit-scrollbar-thumb {
background: #3d3020;
border-radius: 3px;
}
::-webkit-scrollbar-thumb:hover {
background: #c9a96e;
}
::selection {
background: #c9a96e33;
color: #f5f0e8;
}
</style><style>
::-webkit-scrollbar {
width: 6px;
}
::-webkit-scrollbar-track {
background: #0e0b09;
}
::-webkit-scrollbar-thumb {
background: #3d3020;
border-radius: 3px;
}
::-webkit-scrollbar-thumb:hover {
background: #c9a96e;
}
::selection {
background: #c9a96e33;
color: #f5f0e8;
}
</style><style>
::-webkit-scrollbar {
width: 6px;
}
::-webkit-scrollbar-track {
background: #0e0b09;
}
::-webkit-scrollbar-thumb {
background: #3d3020;
border-radius: 3px;
}
::-webkit-scrollbar-thumb:hover {
background: #c9a96e;
}
::selection {
background: #c9a96e33;
color: #f5f0e8;
}
</style>This makes even the browser chrome feel like part of AURA's design system.
Example: delayed script loading
For chat widgets or heavy third-party scripts, load them after user interaction rather than on page load. This protects your Core Web Vitals score:
<script>
function loadOnInteraction(src) {
const script = document.createElement("script");
script.src = src;
script.async = true;
document.head.appendChild(script);
}
const events = ["mousedown", "touchstart", "keydown", "scroll"];
function handleInteraction() {
loadOnInteraction("https://your-third-party-script.js");
events.forEach((e) => window.removeEventListener(e, handleInteraction));
}
events.forEach((e) => window.addEventListener(e, handleInteraction));
</script><script>
function loadOnInteraction(src) {
const script = document.createElement("script");
script.src = src;
script.async = true;
document.head.appendChild(script);
}
const events = ["mousedown", "touchstart", "keydown", "scroll"];
function handleInteraction() {
loadOnInteraction("https://your-third-party-script.js");
events.forEach((e) => window.removeEventListener(e, handleInteraction));
}
events.forEach((e) => window.addEventListener(e, handleInteraction));
</script><script>
function loadOnInteraction(src) {
const script = document.createElement("script");
script.src = src;
script.async = true;
document.head.appendChild(script);
}
const events = ["mousedown", "touchstart", "keydown", "scroll"];
function handleInteraction() {
loadOnInteraction("https://your-third-party-script.js");
events.forEach((e) => window.removeEventListener(e, handleInteraction));
}
events.forEach((e) => window.addEventListener(e, handleInteraction));
</script>Replace https://your-third-party-script.js with the script URL from your tool.
Page-specific code injection
For code that should only run on one page — a Calendly embed script on the Contact page, or a specific pixel on the Pricing page — use page-level custom code instead of Site Settings. Right-click the page in the Pages panel → Page Settings → Custom Code. This keeps your global head clean and prevents unnecessary scripts from loading on every page.
Verifying injection
After publishing, open the live page and right-click → View Page Source. Search for your script tag or style block. If it appears in the source, injection is working. If not, check that you clicked Save in Site Settings and republished after adding the code.