CINXE.COM

Migration guide - step-by-step instructions | 2.12.0

<!DOCTYPE html><html lang="en" dir="ltr" data-has-toc data-has-sidebar data-theme="dark" class="astro-qtabznui"> <head><meta charset="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><title>Migration guide - step-by-step instructions | 2.12.0</title><link rel="canonical" href="https://www.netlify.com/sdk/get-started/migration-guide/migration-steps/"/><link rel="sitemap" href="/sitemap-index.xml"/><link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:400,500,700,400italic|Roboto+Mono:400"/><script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer','GTM-NMKKF2M');</script><link rel="sitemap" href="/sitemap-index.xml"/><link rel="shortcut icon" href="/sdk/favicon.svg" type="image/svg+xml"/><meta name="generator" content="Astro v4.15.7"/><meta name="generator" content="Starlight v0.28.1"/><meta property="og:title" content="Migration guide - step-by-step instructions"/><meta property="og:type" content="article"/><meta property="og:url" content="https://www.netlify.com/sdk/get-started/migration-guide/migration-steps/"/><meta property="og:locale" content="en"/><meta property="og:description" content="Learn how to upgrade your existing integration to SDK v2."/><meta property="og:site_name" content="2.12.0"/><meta name="twitter:card" content="summary_large_image"/><meta name="description" content="Learn how to upgrade your existing integration to SDK v2."/><meta property="og:image" content="https://www.netlify.com/sdk/sdk-og.png"/><meta name="twitter:image" content="https://www.netlify.com/sdk/sdk-og.png"/><meta name="slack-app-id" content="A05P27DR8C8"/><script> window.StarlightThemeProvider = (() => { const storedTheme = typeof localStorage !== 'undefined' && localStorage.getItem('starlight-theme'); const theme = storedTheme || (window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark'); document.documentElement.dataset.theme = theme === 'light' ? 'light' : 'dark'; return { updatePickers(theme = storedTheme || 'auto') { document.querySelectorAll('starlight-theme-select').forEach((picker) => { const select = picker.querySelector('select'); if (select) select.value = theme; /** @type {HTMLTemplateElement | null} */ const tmpl = document.querySelector(`#theme-icons`); const newIcon = tmpl && tmpl.content.querySelector('.' + theme); if (newIcon) { const oldIcon = picker.querySelector('svg.label-icon'); if (oldIcon) { oldIcon.replaceChildren(...newIcon.cloneNode(true).childNodes); } } }); }, }; })(); </script><template id="theme-icons"><svg aria-hidden="true" class="light astro-bg6azcwr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M5 12a1 1 0 0 0-1-1H3a1 1 0 0 0 0 2h1a1 1 0 0 0 1-1Zm.64 5-.71.71a1 1 0 0 0 0 1.41 1 1 0 0 0 1.41 0l.71-.71A1 1 0 0 0 5.64 17ZM12 5a1 1 0 0 0 1-1V3a1 1 0 0 0-2 0v1a1 1 0 0 0 1 1Zm5.66 2.34a1 1 0 0 0 .7-.29l.71-.71a1 1 0 1 0-1.41-1.41l-.66.71a1 1 0 0 0 0 1.41 1 1 0 0 0 .66.29Zm-12-.29a1 1 0 0 0 1.41 0 1 1 0 0 0 0-1.41l-.71-.71a1.004 1.004 0 1 0-1.43 1.41l.73.71ZM21 11h-1a1 1 0 0 0 0 2h1a1 1 0 0 0 0-2Zm-2.64 6A1 1 0 0 0 17 18.36l.71.71a1 1 0 0 0 1.41 0 1 1 0 0 0 0-1.41l-.76-.66ZM12 6.5a5.5 5.5 0 1 0 5.5 5.5A5.51 5.51 0 0 0 12 6.5Zm0 9a3.5 3.5 0 1 1 0-7 3.5 3.5 0 0 1 0 7Zm0 3.5a1 1 0 0 0-1 1v1a1 1 0 0 0 2 0v-1a1 1 0 0 0-1-1Z"/></svg> <svg aria-hidden="true" class="dark astro-bg6azcwr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M21.64 13a1 1 0 0 0-1.05-.14 8.049 8.049 0 0 1-3.37.73 8.15 8.15 0 0 1-8.14-8.1 8.59 8.59 0 0 1 .25-2A1 1 0 0 0 8 2.36a10.14 10.14 0 1 0 14 11.69 1 1 0 0 0-.36-1.05Zm-9.5 6.69A8.14 8.14 0 0 1 7.08 5.22v.27a10.15 10.15 0 0 0 10.14 10.14 9.784 9.784 0 0 0 2.1-.22 8.11 8.11 0 0 1-7.18 4.32v-.04Z"/></svg> <svg aria-hidden="true" class="auto astro-bg6azcwr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M21 14h-1V7a3 3 0 0 0-3-3H7a3 3 0 0 0-3 3v7H3a1 1 0 0 0-1 1v2a3 3 0 0 0 3 3h14a3 3 0 0 0 3-3v-2a1 1 0 0 0-1-1ZM6 7a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v7H6V7Zm14 10a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-1h16v1Z"/></svg> </template><link rel="stylesheet" href="/_astro/index.C6Sq_s6n.css"> <style>:root{--sl-badge-default-border: var(--sl-color-accent);--sl-badge-default-bg: var(--sl-color-accent-low);--sl-badge-default-text: #fff;--sl-badge-note-border: var(--sl-color-blue);--sl-badge-note-bg: var(--sl-color-blue-low);--sl-badge-note-text: #fff;--sl-badge-danger-border: var(--sl-color-red);--sl-badge-danger-bg: var(--sl-color-red-low);--sl-badge-danger-text: #fff;--sl-badge-success-border: var(--sl-color-green);--sl-badge-success-bg: var(--sl-color-green-low);--sl-badge-success-text: #fff;--sl-badge-caution-border: var(--sl-color-orange);--sl-badge-caution-bg: var(--sl-color-orange-low);--sl-badge-caution-text: #fff;--sl-badge-tip-border: var(--sl-color-purple);--sl-badge-tip-bg: var(--sl-color-purple-low);--sl-badge-tip-text: #fff}[data-theme=light]:root{--sl-badge-default-bg: var(--sl-color-accent-high);--sl-badge-note-bg: var(--sl-color-blue-high);--sl-badge-danger-bg: var(--sl-color-red-high);--sl-badge-success-bg: var(--sl-color-green-high);--sl-badge-caution-bg: var(--sl-color-orange-high);--sl-badge-tip-bg: var(--sl-color-purple-high)}.sl-badge:where(.astro-uhv2njfm){display:inline-block;border:1px solid var(--sl-color-border-badge);border-radius:.25rem;font-family:var(--sl-font-system-mono);line-height:normal;color:var(--sl-color-text-badge);background-color:var(--sl-color-bg-badge);overflow-wrap:anywhere}.sidebar-content .sl-badge:where(.astro-uhv2njfm){line-height:1;font-size:var(--sl-text-xs);padding:.125rem .375rem}.sidebar-content a[aria-current=page]>.sl-badge:where(.astro-uhv2njfm){--sl-color-bg-badge: transparent;--sl-color-border-badge: currentColor;color:inherit}.default:where(.astro-uhv2njfm){--sl-color-bg-badge: var(--sl-badge-default-bg);--sl-color-border-badge: var(--sl-badge-default-border);--sl-color-text-badge: var(--sl-badge-default-text)}.note:where(.astro-uhv2njfm){--sl-color-bg-badge: var(--sl-badge-note-bg);--sl-color-border-badge: var(--sl-badge-note-border);--sl-color-text-badge: var(--sl-badge-note-text)}.danger:where(.astro-uhv2njfm){--sl-color-bg-badge: var(--sl-badge-danger-bg);--sl-color-border-badge: var(--sl-badge-danger-border);--sl-color-text-badge: var(--sl-badge-danger-text)}.success:where(.astro-uhv2njfm){--sl-color-bg-badge: var(--sl-badge-success-bg);--sl-color-border-badge: var(--sl-badge-success-border);--sl-color-text-badge: var(--sl-badge-success-text)}.tip:where(.astro-uhv2njfm){--sl-color-bg-badge: var(--sl-badge-tip-bg);--sl-color-border-badge: var(--sl-badge-tip-border);--sl-color-text-badge: var(--sl-badge-tip-text)}.caution:where(.astro-uhv2njfm){--sl-color-bg-badge: var(--sl-badge-caution-bg);--sl-color-border-badge: var(--sl-badge-caution-border);--sl-color-text-badge: var(--sl-badge-caution-text)}.small:where(.astro-uhv2njfm){font-size:var(--sl-text-xs);padding:.125rem .25rem}.medium:where(.astro-uhv2njfm){font-size:var(--sl-text-sm);padding:.175rem .35rem}.large:where(.astro-uhv2njfm){font-size:var(--sl-text-base);padding:.225rem .45rem}.sl-markdown-content :is(h1,h2,h3,h4,h5,h6) .sl-badge:where(.astro-uhv2njfm){vertical-align:middle} svg:where(.astro-bg6azcwr){color:var(--sl-icon-color);font-size:var(--sl-icon-size, 1em);width:1em;height:1em} starlight-tabs:where(.astro-ui5sftem){display:block}.tablist-wrapper:where(.astro-ui5sftem){overflow-x:auto}:where(.astro-ui5sftem)[role=tablist]{display:flex;list-style:none;border-bottom:2px solid var(--sl-color-gray-5);padding:0}.tab:where(.astro-ui5sftem){margin-bottom:-2px}.tab:where(.astro-ui5sftem)>:where(.astro-ui5sftem)[role=tab]{display:flex;align-items:center;gap:.5rem;padding:0 1.25rem;text-decoration:none;border-bottom:2px solid var(--sl-color-gray-5);color:var(--sl-color-gray-3);outline-offset:var(--sl-outline-offset-inside);overflow-wrap:initial}.tab:where(.astro-ui5sftem) :where(.astro-ui5sftem)[role=tab][aria-selected=true]{color:var(--sl-color-white);border-color:var(--sl-color-text-accent);font-weight:600}.tablist-wrapper:where(.astro-ui5sftem)~[role=tabpanel]{margin-top:1rem} .sl-steps{--bullet-size: calc(var(--sl-line-height) * 1rem);--bullet-margin: .375rem;list-style:none;counter-reset:steps-counter var(--sl-steps-start, 0);padding-inline-start:0}.sl-steps>li{counter-increment:steps-counter;position:relative;padding-inline-start:calc(var(--bullet-size) + 1rem);padding-bottom:1px;min-height:calc(var(--bullet-size) + var(--bullet-margin))}.sl-steps>li+li{margin-top:0}.sl-steps>li:before{content:counter(steps-counter);position:absolute;top:0;inset-inline-start:0;width:var(--bullet-size);height:var(--bullet-size);line-height:var(--bullet-size);font-size:var(--sl-text-xs);font-weight:600;text-align:center;color:var(--sl-color-white);background-color:var(--sl-color-gray-6);border-radius:99rem;box-shadow:inset 0 0 0 1px var(--sl-color-gray-5)}.sl-steps>li:after{--guide-width: 1px;content:"";position:absolute;top:calc(var(--bullet-size) + var(--bullet-margin));bottom:var(--bullet-margin);inset-inline-start:calc((var(--bullet-size) - var(--guide-width)) / 2);width:var(--guide-width);background-color:var(--sl-color-hairline-light)}.sl-steps>li>:first-child{--lh: calc(1em * var(--sl-line-height));--shift-y: calc(.5 * (var(--bullet-size) - var(--lh)));transform:translateY(var(--shift-y));margin-bottom:var(--shift-y)}.sl-steps>li>:first-child:where(h1,h2,h3,h4,h5,h6){--lh: calc(1em * var(--sl-line-height-headings))}@supports (--prop: 1lh){.sl-steps>li>:first-child{--lh: 1lh}} .sl-link-button:where(.astro-dbfafs4m){align-items:center;border:1px solid transparent;border-radius:999rem;display:inline-flex;font-size:var(--sl-text-sm);gap:.5em;line-height:1.1875;outline-offset:.25rem;padding:.4375rem 1.125rem;text-decoration:none}.sl-link-button:where(.astro-dbfafs4m).primary{background:var(--sl-color-text-accent);border-color:var(--sl-color-text-accent);color:var(--sl-color-black)}.sl-link-button:where(.astro-dbfafs4m).primary:hover{color:var(--sl-color-black)}.sl-link-button:where(.astro-dbfafs4m).secondary{border-color:inherit;color:var(--sl-color-white)}.sl-link-button:where(.astro-dbfafs4m).minimal{color:var(--sl-color-white);padding-inline:0}.sl-link-button:where(.astro-dbfafs4m) svg{flex-shrink:0}@media (min-width: 50rem){.sl-link-button:where(.astro-dbfafs4m){font-size:var(--sl-text-base);padding:.9375rem 1.25rem}}.sl-markdown-content .sl-link-button:where(.astro-dbfafs4m){margin-inline-end:1rem}.sl-markdown-content .sl-link-button:where(.astro-dbfafs4m):not(:where(p *)){margin-block:1rem} </style><script type="module" src="/_astro/hoisted.C4op7Ona.js"></script> <script type="module" src="/_astro/page.7qqag-5g.js"></script><style>div:where(.astro-fr5qezfu){border:1px solid var(--colorGrayLight);color:var(--colorTextMutedInverse);border-radius:var(--bigRadius);box-shadow:0 2px 4px #0e1e251f;padding:.4rem .6rem;margin-top:.8rem;width:-moz-fit-content;width:fit-content;[data-theme=dark] &{border-color:var(--colorGray)}}:root div:where(.astro-fr5qezfu){font-size:var(--defaultText)}:root .beta-badge:where(.astro-fr5qezfu){color:var(--colorWarningText);background-color:var(--colorWarningLight);padding-left:6px;padding-right:6px;border-radius:40px;text-decoration:none;font-weight:var(--bold);[data-theme=dark] &{color:var(--facetsGold200)}}:root .beta-badge:where(.astro-fr5qezfu):hover{color:var(--colorWarning);text-decoration:underline} </style><style>div:where(.astro-taqzzmlm){border:1px solid var(--colorGrayLight);border-radius:var(--bigRadius);box-shadow:0 2px 4px #0e1e251f;padding:.4rem .6rem;margin-top:.8rem;width:-moz-fit-content;width:fit-content}:root div:where(.astro-taqzzmlm){font-size:var(--defaultText)}:root .beta-badge:where(.astro-taqzzmlm){color:var(--colorWarningText);background-color:var(--colorWarningLight);padding-left:6px;padding-right:6px;border-radius:40px;text-decoration:none;font-weight:var(--bold)}:root .beta-badge:where(.astro-taqzzmlm):hover{color:var(--colorWarning);text-decoration:underline} </style><style>:root[data-theme=dark] #svg-downvote circle{fill:var(--facetsRed900)}:root[data-theme=dark] #svg-downvote circle:hover{fill:var(--facetsRed800)}:root[data-theme=dark] #svg-downvote path{color:var(--facetsRed400)}:root[data-theme=dark] #downvote:checked+label #svg-downvote circle{fill:var(--facetsRed800)}#svg-downvote path{color:#6b2120}#svg-downvote circle{fill:var(--facetsRed000)}#svg-downvote circle:hover{fill:var(--facetsRed100)}#downvote:checked+label #svg-downvote circle{fill:var(--facetsRed400)} </style><style>#none:where(.astro-77rygnu7){display:none}#upvote:where(.astro-77rygnu7),#downvote:where(.astro-77rygnu7){height:0;opacity:0;position:absolute;width:0}#upvote:where(.astro-77rygnu7),#downvote:where(.astro-77rygnu7)+svg:where(.astro-77rygnu7){cursor:pointer}.vote-button:where(.astro-77rygnu7){align-items:center;background:transparent;border:none;cursor:pointer;display:flex;height:100%;justify-content:center;margin:10px;padding:0;width:100%}form:where(.astro-77rygnu7)[name=feedback] .votes:where(.astro-77rygnu7){display:flex;margin-top:0}.feedback:where(.astro-77rygnu7){align-items:center;display:flex;flex-direction:row;flex-wrap:wrap;justify-content:space-between}textarea:where(.astro-77rygnu7){background-color:var(--colorBg);border:1px solid var(--colorBorder);border-radius:var(--bigRadius);margin:1.25rem 0;min-height:130px;padding:.5rem 1rem;transition:box-shadow ease-in-out var(--transitionDuration);width:100%}textarea:where(.astro-77rygnu7):focus{box-shadow:0 0 0 2px var(--colorTeal),0 0 1px 0 var(--colorGrayDarkest);outline:2px solid transparent}form:where(.astro-77rygnu7)[name=feedback] .form-submit:where(.astro-77rygnu7){background-color:var(--colorButtonSecondary);border:none;border-radius:var(--smallRadius);color:var(--colorButtonSecondaryText);cursor:pointer;font-family:var(--fontFamilyHeading);font-size:var(--defaultText);font-weight:600;line-height:1;margin:0;min-width:20%;padding:.75rem 1.5rem;transition:all var(--transitionDurationShort)}form:where(.astro-77rygnu7)[name=feedback] .form-submit:where(.astro-77rygnu7):hover{background-color:var(--colorButtonSecondaryHover)}form:where(.astro-77rygnu7)[name=feedback] .form-submit:where(.astro-77rygnu7):disabled{background-color:var(--colorButtonTertiary);color:var(--colorTextNeutral);cursor:not-allowed}form:where(.astro-77rygnu7)[name=feedback],.success-message:where(.astro-77rygnu7){border-top:1px solid var(--sl-color-hairline);margin-top:3rem;padding:1.5rem 0}form:where(.astro-77rygnu7)[name=feedback] .feedback:where(.astro-77rygnu7) h4:where(.astro-77rygnu7),.success-message:where(.astro-77rygnu7) h4:where(.astro-77rygnu7){font-family:var(--sl-font-system);font-size:1.25rem;font-weight:600;margin:1em 0}form:where(.astro-77rygnu7)[name=feedback] .feedback:where(.astro-77rygnu7) p:where(.astro-77rygnu7),.success-message:where(.astro-77rygnu7) p:where(.astro-77rygnu7){margin:0 0 .75rem}.hidden:where(.astro-77rygnu7){visibility:hidden}.success-message:where(.astro-77rygnu7){display:none} </style><style>footer:where(.astro-sz7xmlte){border-top:1px solid var(--sl-color-hairline);padding:1rem 0}.footer_nav:where(.astro-sz7xmlte){list-style-type:none;display:flex;padding-inline-start:0;justify-content:center}.footer_nav:where(.astro-sz7xmlte) li:where(.astro-sz7xmlte){margin:.25rem 1rem 1rem 0;font-size:15px}.footer_nav:where(.astro-sz7xmlte) li:where(.astro-sz7xmlte) a:where(.astro-sz7xmlte){color:var(--sl-color-text);text-decoration:none}.footer_copyright:where(.astro-sz7xmlte){font-size:15px;text-align:center} </style><style>.netlify-panel:where(.astro-vweeohgf){line-height:1.15;border-left-style:solid;border-left-width:var(--micro);margin:var(--tiny) 0;padding:var(--tiny) var(--small) var(--micro);border-radius:8px;&.warning{background-color:var(--colorWarningLight);border-color:var(--colorWarning);.title,.panel-content,#question-icon{color:var(--colorWarningText)}& p a{color:var(--colorWarningText)}}&.note{background-color:var(--colorNoteLight);border-color:var(--colorNote);.title,.panel-content,#question-icon{color:var(--colorNoteText)}& p a{color:var(--colorNoteText)}}&.tip{background-color:var(--colorTipLight);border-color:var(--colorTip);.title,.panel-content,#question-icon{color:var(--colorTipText)}& p a{color:var(--colorTipText)}}&.danger{background-color:var(--colorDangerLight);border-color:var(--colorDanger);.title,.panel-content,#question-icon{color:var(--colorDangerText)}& p a{color:var(--colorDangerText)}}}.title:where(.astro-vweeohgf){display:flex;font-weight:var(--semibold);font-size:var(--defaultText)}.panel-content:where(.astro-vweeohgf){line-height:1.67;margin-top:var(--micro);margin-bottom:var(--micro);word-wrap:break-word;font-size:var(--smallText)}#icon:where(.astro-vweeohgf){margin-right:.5rem;height:1.3rem;width:1.3rem} </style><style>:root[data-theme=dark] #svg-upvote circle{fill:var(--facetsTeal900)}:root[data-theme=dark] #svg-upvote path{color:var(--facetsTeal200)}:root[data-theme=dark] #svg-upvote circle:hover{fill:var(--facetsTeal700)}:root[data-theme=dark] #upvote:checked+label #svg-upvote circle{fill:var(--facetsTeal700)}#svg-upvote path{color:#145f69}#svg-upvote circle{fill:var(--facetsTeal000)}#svg-upvote circle:hover{fill:var(--facetsTeal100)}#upvote:checked+label #svg-upvote circle{fill:var(--facetsTeal400)} </style><script src="/_astro/FeedbackForm.astro_astro_type_script_index_0_lang.CxPg6FTE.js" type="module"></script><script src="/_astro/Tabs.astro_astro_type_script_index_0_lang.3nBd5krW.js" type="module"></script></head> <body class="astro-qtabznui"> <a href="#_top" class="astro-vf5goutt">Skip to content</a> <div class="page sl-flex astro-37rnjknv"> <header class="header astro-37rnjknv"><div class="header sl-flex astro-azkpog7b"> <div class="title-wrapper sl-flex astro-azkpog7b"> <a href="/" class="site-title sl-flex astro-ldl3wdfq"> <img class="light:sl-hidden astro-ldl3wdfq" alt="Netlify SDK Docs" src="/_astro/logo-dark.CGIhDU-N.svg" width="133" height="40"> <img class="dark:sl-hidden astro-ldl3wdfq" alt="Netlify SDK Docs" src="/_astro/logo-light.Dzqm5Mvw.svg" width="133" height="40"> <span class="astro-ldl3wdfq"> 2.12.0 </span> </a> </div> <div class="sl-flex astro-azkpog7b"> <site-search data-translations="{&#34;placeholder&#34;:&#34;Search&#34;}" class="astro-otpdt6jm"> <button data-open-modal disabled aria-label="Search" aria-keyshortcuts="Control+K" class="astro-otpdt6jm"> <svg aria-hidden="true" class="astro-otpdt6jm astro-bg6azcwr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M21.71 20.29 18 16.61A9 9 0 1 0 16.61 18l3.68 3.68a.999.999 0 0 0 1.42 0 1 1 0 0 0 0-1.39ZM11 18a7 7 0 1 1 0-14 7 7 0 0 1 0 14Z"/></svg> <span class="sl-hidden md:sl-block astro-otpdt6jm" aria-hidden="true">Search</span> <kbd class="sl-hidden md:sl-flex astro-otpdt6jm" style="display: none;"> <kbd class="astro-otpdt6jm">Ctrl</kbd><kbd class="astro-otpdt6jm">K</kbd> </kbd> </button> <dialog style="padding:0" aria-label="Search" class="astro-otpdt6jm"> <div class="dialog-frame sl-flex astro-otpdt6jm"> <button data-close-modal class="sl-flex md:sl-hidden astro-otpdt6jm"> Cancel </button> <div class="search-container astro-otpdt6jm"> <div id="starlight__search" class="astro-otpdt6jm"></div> </div> </div> </dialog> </site-search> <script> (() => { const openBtn = document.querySelector("button[data-open-modal]"); const shortcut = openBtn?.querySelector("kbd"); if (!openBtn || !(shortcut instanceof HTMLElement)) return; const platformKey = shortcut.querySelector("kbd"); if (platformKey && /(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)) { platformKey.textContent = "⌘"; openBtn.setAttribute("aria-keyshortcuts", "Meta+K"); } shortcut.style.display = ""; })(); </script> </div> <div class="sl-hidden md:sl-flex right-group astro-azkpog7b"> <div class="sl-flex social-icons astro-azkpog7b"> <a href="https://developers.netlify.com/feed/tag/sdk" class="external-link astro-aycwkagb" target="_blank">Changelog</a> </div> <starlight-theme-select> <label style="--sl-select-width: 6.25em" class="astro-aw4jz2fr"> <span class="sr-only astro-aw4jz2fr">Select theme</span> <svg aria-hidden="true" class="icon label-icon astro-aw4jz2fr astro-bg6azcwr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M21 14h-1V7a3 3 0 0 0-3-3H7a3 3 0 0 0-3 3v7H3a1 1 0 0 0-1 1v2a3 3 0 0 0 3 3h14a3 3 0 0 0 3-3v-2a1 1 0 0 0-1-1ZM6 7a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v7H6V7Zm14 10a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-1h16v1Z"/></svg> <select value="auto" class="astro-aw4jz2fr"> <option value="dark" class="astro-aw4jz2fr">Dark</option><option value="light" class="astro-aw4jz2fr">Light</option><option value="auto" selected="true" class="astro-aw4jz2fr">Auto</option> </select> <svg aria-hidden="true" class="icon caret astro-aw4jz2fr astro-bg6azcwr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M17 9.17a1 1 0 0 0-1.41 0L12 12.71 8.46 9.17a1 1 0 1 0-1.41 1.42l4.24 4.24a1.002 1.002 0 0 0 1.42 0L17 10.59a1.002 1.002 0 0 0 0-1.42Z"/></svg> </label> </starlight-theme-select> <script> StarlightThemeProvider.updatePickers(); </script> </div> </div> </header> <nav class="sidebar astro-37rnjknv" aria-label="Main"> <starlight-menu-button class="astro-xncl7wcg"> <button aria-expanded="false" aria-label="Menu" aria-controls="starlight__sidebar" class="sl-flex md:sl-hidden astro-xncl7wcg"> <svg aria-hidden="true" class="astro-xncl7wcg astro-bg6azcwr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M3 8h18a1 1 0 1 0 0-2H3a1 1 0 0 0 0 2Zm18 8H3a1 1 0 0 0 0 2h18a1 1 0 0 0 0-2Zm0-5H3a1 1 0 0 0 0 2h18a1 1 0 0 0 0-2Z"/></svg> </button> </starlight-menu-button> <div id="starlight__sidebar" class="sidebar-pane astro-37rnjknv"> <div class="sidebar-content sl-flex astro-37rnjknv"> <sl-sidebar-state-persist data-hash="0sbvn74" class="astro-hcjnkwvw"> <script> (() => { try { if (!matchMedia('(min-width: 50em)').matches) return; /** @type {HTMLElement | null} */ const target = document.querySelector('sl-sidebar-state-persist'); const state = JSON.parse(sessionStorage.getItem('sl-sidebar-state') || '0'); if (!target || !state || target.dataset.hash !== state.hash) return; window._starlightScrollRestore = state.scroll; customElements.define( 'sl-sidebar-restore', class SidebarRestore extends HTMLElement { connectedCallback() { try { const idx = parseInt(this.dataset.index || ''); const details = this.closest('details'); if (details && typeof state.open[idx] === 'boolean') details.open = state.open[idx]; } catch {} } } ); } catch {} })(); </script> <ul class="top-level astro-lum4h4k6"> <li class="astro-lum4h4k6"> <a href="https://docs.netlify.com/" class="large external-link astro-lum4h4k6" target="_blank" class="external-link"> <span class="astro-lum4h4k6">Netlify user docs</span> </a> </li><li class="astro-lum4h4k6"> <details open class="astro-lum4h4k6"> <sl-sidebar-restore data-index="0"></sl-sidebar-restore> <summary class="astro-lum4h4k6"> <div class="group-label astro-lum4h4k6"> <span class="large astro-lum4h4k6">Get started</span> </div> <svg aria-hidden="true" class="caret astro-lum4h4k6 astro-bg6azcwr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <ul class="astro-lum4h4k6"> <li class="astro-lum4h4k6"> <a href="/sdk/get-started/introduction" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Introduction</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/get-started/create-a-new-extension" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Create a new extension</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/get-started/anatomy-of-an-extension" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Anatomy of an extension</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/get-started/installation-flow" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Installation flow</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/get-started/environment-variables" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Environment variables</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/get-started/requirements-and-limitations" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Requirements &amp; limitations</span> </a> </li><li class="astro-lum4h4k6"> <details open class="astro-lum4h4k6"> <sl-sidebar-restore data-index="10"></sl-sidebar-restore> <summary class="astro-lum4h4k6"> <div class="group-label astro-lum4h4k6"> <span class="large astro-lum4h4k6">Migration guide</span> </div> <svg aria-hidden="true" class="caret astro-lum4h4k6 astro-bg6azcwr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <ul class="astro-lum4h4k6"> <li class="astro-lum4h4k6"> <a href="/sdk/get-started/migration-guide/overview/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Overview</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/get-started/migration-guide/migration-steps/" aria-current="page" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Step-by-step instructions</span> </a> </li> </ul> </details> </li> </ul> </details> </li><li class="astro-lum4h4k6"> <details class="astro-lum4h4k6"> <sl-sidebar-restore data-index="1"></sl-sidebar-restore> <summary class="astro-lum4h4k6"> <div class="group-label astro-lum4h4k6"> <span class="large astro-lum4h4k6">Connectors</span> </div> <svg aria-hidden="true" class="caret astro-lum4h4k6 astro-bg6azcwr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <ul class="astro-lum4h4k6"> <li class="astro-lum4h4k6"> <a href="/sdk/connectors/overview/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Overview</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/connectors/get-started/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Get started</span> </a> </li><li class="astro-lum4h4k6"> <details class="astro-lum4h4k6"> <sl-sidebar-restore data-index="11"></sl-sidebar-restore> <summary class="astro-lum4h4k6"> <div class="group-label astro-lum4h4k6"> <span class="large astro-lum4h4k6">Develop</span> </div> <svg aria-hidden="true" class="caret astro-lum4h4k6 astro-bg6azcwr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <ul class="astro-lum4h4k6"> <li class="astro-lum4h4k6"> <a href="/sdk/connectors/develop/overview/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Overview</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/connectors/develop/define-data-model/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Data model</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/connectors/develop/sync-data/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Sync data</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/connectors/develop/configuration-options/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Configuration options</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/connectors/develop/check-permissions/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Check permissions</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/connectors/develop/write-data/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Write data</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/connectors/develop/manage-assets/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Manage assets</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/connectors/develop/localization/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Localization</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/connectors/develop/scheduled-publishing/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Scheduled publishing</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/connectors/develop/dynamic-connectors/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Dynamic connectors</span> </a> </li> </ul> </details> </li><li class="astro-lum4h4k6"> <a href="/sdk/connectors/build/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Build</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/connectors/debug-and-test/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Debug &amp; test</span> </a> </li> </ul> </details> </li><li class="astro-lum4h4k6"> <details class="astro-lum4h4k6"> <sl-sidebar-restore data-index="2"></sl-sidebar-restore> <summary class="astro-lum4h4k6"> <div class="group-label astro-lum4h4k6"> <span class="large astro-lum4h4k6">Build event handlers</span> </div> <svg aria-hidden="true" class="caret astro-lum4h4k6 astro-bg6azcwr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <ul class="astro-lum4h4k6"> <li class="astro-lum4h4k6"> <a href="/sdk/build-event-handlers/overview/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Overview</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/build-event-handlers/get-started/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Get started</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/build-event-handlers/hook-into-events/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Hook into build events</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/build-event-handlers/values-and-methods/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Values &amp; methods</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/build-event-handlers/debug-and-test/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Debug &amp; test</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/build-event-handlers/migrate-build-plugins/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Migrate Build Plugins</span> </a> </li> </ul> </details> </li><li class="astro-lum4h4k6"> <details class="astro-lum4h4k6"> <sl-sidebar-restore data-index="3"></sl-sidebar-restore> <summary class="astro-lum4h4k6"> <div class="group-label astro-lum4h4k6"> <span class="large astro-lum4h4k6">Functions</span> </div> <svg aria-hidden="true" class="caret astro-lum4h4k6 astro-bg6azcwr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <ul class="astro-lum4h4k6"> <li class="astro-lum4h4k6"> <a href="/sdk/functions/overview/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Overview</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/functions/get-started/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Get started</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/functions/debug-and-test/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Debug &amp; test</span> </a> </li> </ul> </details> </li><li class="astro-lum4h4k6"> <details class="astro-lum4h4k6"> <sl-sidebar-restore data-index="4"></sl-sidebar-restore> <summary class="astro-lum4h4k6"> <div class="group-label astro-lum4h4k6"> <span class="large astro-lum4h4k6">Edge Functions</span> </div> <svg aria-hidden="true" class="caret astro-lum4h4k6 astro-bg6azcwr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <ul class="astro-lum4h4k6"> <li class="astro-lum4h4k6"> <a href="/sdk/edge-functions/overview/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Overview</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/edge-functions/get-started/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Get started</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/edge-functions/debug-and-test/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Debug &amp; test</span> </a> </li> </ul> </details> </li><li class="astro-lum4h4k6"> <details class="astro-lum4h4k6"> <sl-sidebar-restore data-index="5"></sl-sidebar-restore> <summary class="astro-lum4h4k6"> <div class="group-label astro-lum4h4k6"> <span class="large astro-lum4h4k6">Endpoints</span> </div> <svg aria-hidden="true" class="caret astro-lum4h4k6 astro-bg6azcwr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <ul class="astro-lum4h4k6"> <li class="astro-lum4h4k6"> <a href="/sdk/endpoints/overview/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Overview</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/endpoints/get-started/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Get started</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/endpoints/values-and-methods/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Values &amp; methods</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/endpoints/debug-and-test/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Debug &amp; test</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/endpoints/use-cases/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Use cases</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/endpoints/trpc/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">tRPC integration</span> </a> </li> </ul> </details> </li><li class="astro-lum4h4k6"> <details class="astro-lum4h4k6"> <sl-sidebar-restore data-index="6"></sl-sidebar-restore> <summary class="astro-lum4h4k6"> <div class="group-label astro-lum4h4k6"> <span class="large astro-lum4h4k6">Extension UI</span> </div> <svg aria-hidden="true" class="caret astro-lum4h4k6 astro-bg6azcwr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <ul class="astro-lum4h4k6"> <li class="astro-lum4h4k6"> <a href="/sdk/extension-ui/overview/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Overview</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/extension-ui/get-started/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Get started</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/extension-ui/develop-locally/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Develop locally</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/extension-ui/add-a-new-surface/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Add a new surface</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/extension-ui/call-endpoints/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Call endpoints</span> </a> </li> </ul> </details> </li><li class="astro-lum4h4k6"> <details class="astro-lum4h4k6"> <sl-sidebar-restore data-index="7"></sl-sidebar-restore> <summary class="astro-lum4h4k6"> <div class="group-label astro-lum4h4k6"> <span class="large astro-lum4h4k6">OAuth</span> </div> <svg aria-hidden="true" class="caret astro-lum4h4k6 astro-bg6azcwr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <ul class="astro-lum4h4k6"> <li class="astro-lum4h4k6"> <a href="/sdk/oauth/overview/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Overview</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/oauth/get-started/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Get started</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/oauth/best-practices/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Best practices</span> </a> </li> </ul> </details> </li><li class="astro-lum4h4k6"> <details class="astro-lum4h4k6"> <sl-sidebar-restore data-index="8"></sl-sidebar-restore> <summary class="astro-lum4h4k6"> <div class="group-label astro-lum4h4k6"> <span class="large astro-lum4h4k6">Publish and manage</span> </div> <svg aria-hidden="true" class="caret astro-lum4h4k6 astro-bg6azcwr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <ul class="astro-lum4h4k6"> <li class="astro-lum4h4k6"> <a href="/sdk/publish/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Overview</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/publish/publish-extensions/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Publish extensions</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/publish/manage-extensions/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Manage extensions</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/publish/partner-extensions/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Partner extensions</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/publish/deploy-to-netlify-button/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Deploy to Netlify button</span> </a> </li> </ul> </details> </li><li class="astro-lum4h4k6"> <details class="astro-lum4h4k6"> <sl-sidebar-restore data-index="9"></sl-sidebar-restore> <summary class="astro-lum4h4k6"> <div class="group-label astro-lum4h4k6"> <span class="large astro-lum4h4k6">Reference docs</span> </div> <svg aria-hidden="true" class="caret astro-lum4h4k6 astro-bg6azcwr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <ul class="astro-lum4h4k6"> <li class="astro-lum4h4k6"> <a href="/sdk/reference/overview" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Overview</span> </a> </li><li class="astro-lum4h4k6"> <details open class="astro-lum4h4k6"> <sl-sidebar-restore data-index="12"></sl-sidebar-restore> <summary class="astro-lum4h4k6"> <div class="group-label astro-lum4h4k6"> <span class="large astro-lum4h4k6">SDK</span> </div> <svg aria-hidden="true" class="caret astro-lum4h4k6 astro-bg6azcwr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <ul class="astro-lum4h4k6"> <li class="astro-lum4h4k6"> <details class="astro-lum4h4k6"> <sl-sidebar-restore data-index="14"></sl-sidebar-restore> <summary class="astro-lum4h4k6"> <div class="group-label astro-lum4h4k6"> <span class="large astro-lum4h4k6">Classes</span> </div> <svg aria-hidden="true" class="caret astro-lum4h4k6 astro-bg6azcwr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <ul class="astro-lum4h4k6"> <li class="astro-lum4h4k6"> <details class="astro-lum4h4k6"> <sl-sidebar-restore data-index="17"></sl-sidebar-restore> <summary class="astro-lum4h4k6"> <div class="group-label astro-lum4h4k6"> <span class="large astro-lum4h4k6">NetlifyConnector</span> </div> <svg aria-hidden="true" class="caret astro-lum4h4k6 astro-bg6azcwr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <ul class="astro-lum4h4k6"> <li class="astro-lum4h4k6"> <a href="/sdk/reference/classes/netlifyconnector/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Overview</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/reference/classes/netlifyconnector/assets/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">assets</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/reference/classes/netlifyconnector/documents/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">documents</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/reference/classes/netlifyconnector/hasaccess/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">hasAccess</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/reference/classes/netlifyconnector/init/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">init</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/reference/classes/netlifyconnector/model/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">model</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/reference/classes/netlifyconnector/proxyschema/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">proxySchema</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/reference/classes/netlifyconnector/scheduledactions/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">scheduledActions</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/reference/classes/netlifyconnector/sync/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">sync</span> </a> </li> </ul> </details> </li><li class="astro-lum4h4k6"> <a href="/sdk/reference/classes/netlifyextension/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">NetlifyExtension</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/reference/classes/netlifyextensionclient/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">NetlifyExtensionClient</span> </a> </li> </ul> </details> </li><li class="astro-lum4h4k6"> <a href="/sdk/reference/interfaces" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Interfaces</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/reference/commands" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Commands</span> </a> </li> </ul> </details> </li><li class="astro-lum4h4k6"> <details open class="astro-lum4h4k6"> <sl-sidebar-restore data-index="13"></sl-sidebar-restore> <summary class="astro-lum4h4k6"> <div class="group-label astro-lum4h4k6"> <span class="large astro-lum4h4k6">React</span> </div> <svg aria-hidden="true" class="caret astro-lum4h4k6 astro-bg6azcwr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <ul class="astro-lum4h4k6"> <li class="astro-lum4h4k6"> <details class="astro-lum4h4k6"> <sl-sidebar-restore data-index="15"></sl-sidebar-restore> <summary class="astro-lum4h4k6"> <div class="group-label astro-lum4h4k6"> <span class="large astro-lum4h4k6">@netlify/sdk/react</span> </div> <svg aria-hidden="true" class="caret astro-lum4h4k6 astro-bg6azcwr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <ul class="astro-lum4h4k6"> <li class="astro-lum4h4k6"> <details class="astro-lum4h4k6"> <sl-sidebar-restore data-index="18"></sl-sidebar-restore> <summary class="astro-lum4h4k6"> <div class="group-label astro-lum4h4k6"> <span class="large astro-lum4h4k6">Enumerations</span> </div> <svg aria-hidden="true" class="caret astro-lum4h4k6 astro-bg6azcwr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <ul class="astro-lum4h4k6"> <li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/enumerations/surfaces/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Surfaces</span> </a> </li> </ul> </details> </li><li class="astro-lum4h4k6"> <details class="astro-lum4h4k6"> <sl-sidebar-restore data-index="19"></sl-sidebar-restore> <summary class="astro-lum4h4k6"> <div class="group-label astro-lum4h4k6"> <span class="large astro-lum4h4k6">Functions</span> </div> <svg aria-hidden="true" class="caret astro-lum4h4k6 astro-bg6azcwr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <ul class="astro-lum4h4k6"> <li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/functions/usenetlifyextensionuifetch/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">useNetlifyExtensionUIFetch</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/functions/usenetlifysdk/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">useNetlifySDK</span> </a> </li> </ul> </details> </li> </ul> </details> </li><li class="astro-lum4h4k6"> <details class="astro-lum4h4k6"> <sl-sidebar-restore data-index="16"></sl-sidebar-restore> <summary class="astro-lum4h4k6"> <div class="group-label astro-lum4h4k6"> <span class="large astro-lum4h4k6">@netlify/sdk/react/components</span> </div> <svg aria-hidden="true" class="caret astro-lum4h4k6 astro-bg6azcwr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <ul class="astro-lum4h4k6"> <li class="astro-lum4h4k6"> <details class="astro-lum4h4k6"> <sl-sidebar-restore data-index="20"></sl-sidebar-restore> <summary class="astro-lum4h4k6"> <div class="group-label astro-lum4h4k6"> <span class="large astro-lum4h4k6">Type Aliases</span> </div> <svg aria-hidden="true" class="caret astro-lum4h4k6 astro-bg6azcwr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <ul class="astro-lum4h4k6"> <li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/type-aliases/alertprops/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">AlertProps</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/type-aliases/buttongroupprops/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">ButtonGroupProps</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/type-aliases/buttonprops/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">ButtonProps</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/type-aliases/cardfooterprops/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">CardFooterProps</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/type-aliases/cardprops/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">CardProps</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/type-aliases/cardtitleprops/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">CardTitleProps</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/type-aliases/checkboxprops/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">CheckboxProps</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/type-aliases/clipboardbuttonprops/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">ClipboardButtonProps</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/type-aliases/codeblockprops/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">CodeBlockProps</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/type-aliases/connectconfigurationsurfaceprops/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">ConnectConfigurationSurfaceProps</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/type-aliases/decorativeiconprops/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">DecorativeIconProps</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/type-aliases/extensionsettingsprops/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">ExtensionSettingsProps</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/type-aliases/linkprops/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">LinkProps</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/type-aliases/listloaderprops/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">ListLoaderProps</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/type-aliases/netlifyextensionuiprops/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">NetlifyExtensionUIProps</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/type-aliases/selectprops/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">SelectProps</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/type-aliases/settingscardprops/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">SettingsCardProps</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/type-aliases/siteaccessconfigurationsurfaceprops/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">SiteAccessConfigurationSurfaceProps</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/type-aliases/sitebuilddeployconfigurationsurfaceprops/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">SiteBuildDeployConfigurationSurfaceProps</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/type-aliases/siteconfigurationsurfaceprops/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">SiteConfigurationSurfaceProps</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/type-aliases/sitegeneralconfigurationsurfaceprops/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">SiteGeneralConfigurationSurfaceProps</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/type-aliases/sitenotificationsconfigurationsurfaceprops/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">SiteNotificationsConfigurationSurfaceProps</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/type-aliases/surfacerouteprops/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">SurfaceRouteProps</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/type-aliases/surfacerouterprops/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">SurfaceRouterProps</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/type-aliases/teamconfigurationsurfaceprops/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">TeamConfigurationSurfaceProps</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/type-aliases/visualeditorconfigurationsurfaceprops/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">VisualEditorConfigurationSurfaceProps</span> </a> </li> </ul> </details> </li><li class="astro-lum4h4k6"> <details class="astro-lum4h4k6"> <sl-sidebar-restore data-index="21"></sl-sidebar-restore> <summary class="astro-lum4h4k6"> <div class="group-label astro-lum4h4k6"> <span class="large astro-lum4h4k6">Functions</span> </div> <svg aria-hidden="true" class="caret astro-lum4h4k6 astro-bg6azcwr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <ul class="astro-lum4h4k6"> <li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/functions/alert/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Alert</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/functions/button/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Button</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/functions/buttongroup/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">ButtonGroup</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/functions/card/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Card</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/functions/cardfooter/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">CardFooter</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/functions/cardloader/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">CardLoader</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/functions/cardtitle/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">CardTitle</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/functions/checkbox/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Checkbox</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/functions/clipboardbutton/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">ClipboardButton</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/functions/cn/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">cn</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/functions/codeblock/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">CodeBlock</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/functions/connectconfigurationsurface/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">ConnectConfigurationSurface</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/functions/decorativeicon/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">DecorativeIcon</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/functions/extensionsettings/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">ExtensionSettings</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/functions/extensionsettingsheader/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">ExtensionSettingsHeader</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/functions/form/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Form</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/functions/link/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Link</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/functions/listloader/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">ListLoader</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/functions/providerauthcard/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">ProviderAuthCard</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/functions/select/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">Select</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/functions/siteaccessconfigurationsurface/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">SiteAccessConfigurationSurface</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/functions/sitebuilddeployconfigurationsurface/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">SiteBuildDeployConfigurationSurface</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/functions/siteconfigurationsurface/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">SiteConfigurationSurface</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/functions/sitegeneralconfigurationsurface/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">SiteGeneralConfigurationSurface</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/functions/sitenotificationsconfigurationsurface/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">SiteNotificationsConfigurationSurface</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/functions/surfaceroute/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">SurfaceRoute</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/functions/surfacerouter/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">SurfaceRouter</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/functions/teamconfigurationsurface/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">TeamConfigurationSurface</span> </a> </li><li class="astro-lum4h4k6"> <a href="/sdk/api/netlify/sdk/react/components/functions/visualeditorconfigurationsurface/" class="astro-lum4h4k6"> <span class="astro-lum4h4k6">VisualEditorConfigurationSurface</span> </a> </li> </ul> </details> </li> </ul> </details> </li> </ul> </details> </li> </ul> </details> </li><li class="astro-lum4h4k6"> <a href="https://developers.netlify.com/feed/tag/sdk" class="large external-link margin-top astro-lum4h4k6" target="_blank" class="external-link margin-top"> <span class="astro-lum4h4k6">Changelog</span> </a> </li><li class="astro-lum4h4k6"> <a href="https://answers.netlify.com/" class="large text-sm external-link margin-top astro-lum4h4k6" target="_blank" class="text-sm external-link margin-top"> <span class="astro-lum4h4k6">Forums</span> </a> </li><li class="astro-lum4h4k6"> <a href="https://www.netlify.com/support/" class="large text-sm external-link astro-lum4h4k6" target="_blank" class="text-sm external-link"> <span class="astro-lum4h4k6">Contact support</span> </a> </li> </ul> <script> (() => { const scroller = document.getElementById('starlight__sidebar'); if (!window._starlightScrollRestore || !scroller) return; scroller.scrollTop = window._starlightScrollRestore; delete window._starlightScrollRestore; })(); </script> </sl-sidebar-state-persist> <div class="md:sl-hidden"> <div class="mobile-preferences sl-flex astro-tyavstbm"> <div class="sl-flex social-icons astro-tyavstbm"> <a href="https://developers.netlify.com/feed/tag/sdk" class="external-link astro-aycwkagb" target="_blank">Changelog</a> </div> <starlight-theme-select> <label style="--sl-select-width: 6.25em" class="astro-aw4jz2fr"> <span class="sr-only astro-aw4jz2fr">Select theme</span> <svg aria-hidden="true" class="icon label-icon astro-aw4jz2fr astro-bg6azcwr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M21 14h-1V7a3 3 0 0 0-3-3H7a3 3 0 0 0-3 3v7H3a1 1 0 0 0-1 1v2a3 3 0 0 0 3 3h14a3 3 0 0 0 3-3v-2a1 1 0 0 0-1-1ZM6 7a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v7H6V7Zm14 10a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-1h16v1Z"/></svg> <select value="auto" class="astro-aw4jz2fr"> <option value="dark" class="astro-aw4jz2fr">Dark</option><option value="light" class="astro-aw4jz2fr">Light</option><option value="auto" selected="true" class="astro-aw4jz2fr">Auto</option> </select> <svg aria-hidden="true" class="icon caret astro-aw4jz2fr astro-bg6azcwr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M17 9.17a1 1 0 0 0-1.41 0L12 12.71 8.46 9.17a1 1 0 1 0-1.41 1.42l4.24 4.24a1.002 1.002 0 0 0 1.42 0L17 10.59a1.002 1.002 0 0 0 0-1.42Z"/></svg> </label> </starlight-theme-select> <script> StarlightThemeProvider.updatePickers(); </script> </div> </div> </div> </div> </nav> <div class="main-frame astro-37rnjknv"> <div class="lg:sl-flex astro-hpgkqabp"> <aside class="right-sidebar-container astro-hpgkqabp"> <div class="right-sidebar astro-hpgkqabp"> <div class="lg:sl-hidden astro-tnnf5i73"><mobile-starlight-toc data-min-h="2" data-max-h="2" class="astro-gtjotjxs"><nav aria-labelledby="starlight__on-this-page--mobile" class="astro-gtjotjxs"><details id="starlight__mobile-toc" class="astro-gtjotjxs"><summary id="starlight__on-this-page--mobile" class="sl-flex astro-gtjotjxs"><div class="toggle sl-flex astro-gtjotjxs">On this page<svg aria-hidden="true" class="caret astro-gtjotjxs astro-bg6azcwr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </div><span class="display-current astro-gtjotjxs"></span></summary><div class="dropdown astro-gtjotjxs"><ul class="isMobile astro-qbq4w3iz" style="--depth: 0;"> <li class="astro-qbq4w3iz" style="--depth: 0;"> <a href="#_top" class="astro-qbq4w3iz" style="--depth: 0;"> <span class="astro-qbq4w3iz" style="--depth: 0;">Overview</span> </a> </li><li class="astro-qbq4w3iz" style="--depth: 0;"> <a href="#0-prepare-to-migrate" class="astro-qbq4w3iz" style="--depth: 0;"> <span class="astro-qbq4w3iz" style="--depth: 0;">0. Prepare to migrate</span> </a> </li><li class="astro-qbq4w3iz" style="--depth: 0;"> <a href="#1-update-dependencies" class="astro-qbq4w3iz" style="--depth: 0;"> <span class="astro-qbq4w3iz" style="--depth: 0;">1. Update dependencies</span> </a> </li><li class="astro-qbq4w3iz" style="--depth: 0;"> <a href="#2-update-files-in-the-project-root-folder" class="astro-qbq4w3iz" style="--depth: 0;"> <span class="astro-qbq4w3iz" style="--depth: 0;">2. Update files in the project root folder</span> </a> </li><li class="astro-qbq4w3iz" style="--depth: 0;"> <a href="#3-edit-methods-that-have-been-replaced-or-updated" class="astro-qbq4w3iz" style="--depth: 0;"> <span class="astro-qbq4w3iz" style="--depth: 0;">3. Edit methods that have been replaced or updated</span> </a> </li><li class="astro-qbq4w3iz" style="--depth: 0;"> <a href="#4-remove-methods-and-fields-that-no-longer-exist" class="astro-qbq4w3iz" style="--depth: 0;"> <span class="astro-qbq4w3iz" style="--depth: 0;">4. Remove methods and fields that no longer exist</span> </a> </li><li class="astro-qbq4w3iz" style="--depth: 0;"> <a href="#5-replace-integration-ui-with-extension-ui" class="astro-qbq4w3iz" style="--depth: 0;"> <span class="astro-qbq4w3iz" style="--depth: 0;">5. Replace Integration UI with extension UI</span> </a> </li><li class="astro-qbq4w3iz" style="--depth: 0;"> <a href="#6-update-code-for-connectors" class="astro-qbq4w3iz" style="--depth: 0;"> <span class="astro-qbq4w3iz" style="--depth: 0;">6. Update code for connectors</span> </a> </li><li class="astro-qbq4w3iz" style="--depth: 0;"> <a href="#7-publish-a-private-extension-to-test-in-production" class="astro-qbq4w3iz" style="--depth: 0;"> <span class="astro-qbq4w3iz" style="--depth: 0;">7. Publish a private extension to test in production</span> </a> </li><li class="astro-qbq4w3iz" style="--depth: 0;"> <a href="#8-replace-your-published-integration-with-the-new-extension" class="astro-qbq4w3iz" style="--depth: 0;"> <span class="astro-qbq4w3iz" style="--depth: 0;">8. Replace your published integration with the new extension</span> </a> </li><li class="astro-qbq4w3iz" style="--depth: 0;"> <a href="#contact-us-for-support" class="astro-qbq4w3iz" style="--depth: 0;"> <span class="astro-qbq4w3iz" style="--depth: 0;">Contact us for support</span> </a> </li> </ul> </div></details></nav></mobile-starlight-toc></div><div class="right-sidebar-panel sl-hidden lg:sl-block astro-tnnf5i73"><div class="sl-container astro-tnnf5i73"><starlight-toc data-min-h="2" data-max-h="2"><nav aria-labelledby="starlight__on-this-page"><h2 id="starlight__on-this-page">On this page</h2><ul class="astro-qbq4w3iz" style="--depth: 0;"> <li class="astro-qbq4w3iz" style="--depth: 0;"> <a href="#_top" class="astro-qbq4w3iz" style="--depth: 0;"> <span class="astro-qbq4w3iz" style="--depth: 0;">Overview</span> </a> </li><li class="astro-qbq4w3iz" style="--depth: 0;"> <a href="#0-prepare-to-migrate" class="astro-qbq4w3iz" style="--depth: 0;"> <span class="astro-qbq4w3iz" style="--depth: 0;">0. Prepare to migrate</span> </a> </li><li class="astro-qbq4w3iz" style="--depth: 0;"> <a href="#1-update-dependencies" class="astro-qbq4w3iz" style="--depth: 0;"> <span class="astro-qbq4w3iz" style="--depth: 0;">1. Update dependencies</span> </a> </li><li class="astro-qbq4w3iz" style="--depth: 0;"> <a href="#2-update-files-in-the-project-root-folder" class="astro-qbq4w3iz" style="--depth: 0;"> <span class="astro-qbq4w3iz" style="--depth: 0;">2. Update files in the project root folder</span> </a> </li><li class="astro-qbq4w3iz" style="--depth: 0;"> <a href="#3-edit-methods-that-have-been-replaced-or-updated" class="astro-qbq4w3iz" style="--depth: 0;"> <span class="astro-qbq4w3iz" style="--depth: 0;">3. Edit methods that have been replaced or updated</span> </a> </li><li class="astro-qbq4w3iz" style="--depth: 0;"> <a href="#4-remove-methods-and-fields-that-no-longer-exist" class="astro-qbq4w3iz" style="--depth: 0;"> <span class="astro-qbq4w3iz" style="--depth: 0;">4. Remove methods and fields that no longer exist</span> </a> </li><li class="astro-qbq4w3iz" style="--depth: 0;"> <a href="#5-replace-integration-ui-with-extension-ui" class="astro-qbq4w3iz" style="--depth: 0;"> <span class="astro-qbq4w3iz" style="--depth: 0;">5. Replace Integration UI with extension UI</span> </a> </li><li class="astro-qbq4w3iz" style="--depth: 0;"> <a href="#6-update-code-for-connectors" class="astro-qbq4w3iz" style="--depth: 0;"> <span class="astro-qbq4w3iz" style="--depth: 0;">6. Update code for connectors</span> </a> </li><li class="astro-qbq4w3iz" style="--depth: 0;"> <a href="#7-publish-a-private-extension-to-test-in-production" class="astro-qbq4w3iz" style="--depth: 0;"> <span class="astro-qbq4w3iz" style="--depth: 0;">7. Publish a private extension to test in production</span> </a> </li><li class="astro-qbq4w3iz" style="--depth: 0;"> <a href="#8-replace-your-published-integration-with-the-new-extension" class="astro-qbq4w3iz" style="--depth: 0;"> <span class="astro-qbq4w3iz" style="--depth: 0;">8. Replace your published integration with the new extension</span> </a> </li><li class="astro-qbq4w3iz" style="--depth: 0;"> <a href="#contact-us-for-support" class="astro-qbq4w3iz" style="--depth: 0;"> <span class="astro-qbq4w3iz" style="--depth: 0;">Contact us for support</span> </a> </li> </ul> </nav></starlight-toc></div></div> </div> </aside> <div class="main-pane astro-hpgkqabp"> <main data-pagefind-body lang="en" dir="ltr" class="astro-qtabznui"> <div class="content-panel astro-kdat752j"> <div class="sl-container astro-kdat752j"> <h1 id="_top" class="astro-uqg6c75q">Migration guide - step-by-step instructions</h1> </div> </div> <div class="content-panel astro-kdat752j"> <div class="sl-container astro-kdat752j"> <div class="sl-markdown-content"> <p>We recommend following the migration steps in order. If you have questions, please <a href="https://www.netlify.com/support/" class="external-link" rel="noopener noreferrer" target="_blank">contact us</a>.</p> <div class="netlify-panel warning astro-vweeohgf"> <p class="title astro-vweeohgf"> <span id="icon" class="astro-vweeohgf"><svg width="1em" height="1em" viewBox="0 0 24 24" class="astro-vweeohgf" data-icon="uil:exclamation-triangle"> <symbol id="ai:uil:exclamation-triangle"><path fill="currentColor" d="M12 16a1 1 0 1 0 1 1a1 1 0 0 0-1-1m10.67 1.47l-8.05-14a3 3 0 0 0-5.24 0l-8 14A3 3 0 0 0 3.94 22h16.12a3 3 0 0 0 2.61-4.53m-1.73 2a1 1 0 0 1-.88.51H3.94a1 1 0 0 1-.88-.51a1 1 0 0 1 0-1l8-14a1 1 0 0 1 1.78 0l8.05 14a1 1 0 0 1 .05 1.02ZM12 8a1 1 0 0 0-1 1v4a1 1 0 0 0 2 0V9a1 1 0 0 0-1-1"/></symbol><use xlink:href="#ai:uil:exclamation-triangle"></use> </svg></span>Avoid breaking changes </p> <div class="panel-content astro-vweeohgf"> <p>Migrating from SDK v1 to v2 should not cause breaking changes for your users. Please avoid including any breaking changes to your extension’s functionality while migrating. If your extension does include breaking changes, please <a href="https://www.netlify.com/support/" class="external-link" rel="noopener noreferrer" target="_blank">contact us</a> to discuss.</p> </div> </div> <h2 id="0-prepare-to-migrate">0. Prepare to migrate</h2> <p>We recommend that you create a temporary site on Netlify to deploy your migrated extension to. You can use this site to install and test the extension in production without impacting your current users.</p> <ol> <li>Create a new Git branch for your extension and push the branch to your repository.</li> <li>Navigate to your team in the Netlify UI and select <strong>Add a new site > Import an existing project</strong>.</li> <li>Follow the prompts to configure a new site based on the branch. Make sure you update the value for <strong>Branch to deploy</strong> and select the branch from step 1.</li> <li>Deploy the site.</li> </ol> <p>As you work on the migration, you can commit and push updates to your Git repository, and then deploy the site to reflect your changes. Once your migrated extension is ready, you can follow the steps documented below to <a href="#8-replace-your-published-integration-with-the-new-extension">replace the published integration with the code from this branch</a>.</p> <h2 id="1-update-dependencies">1. Update dependencies</h2> <p>First, start by updating the required dependencies for your project.</p> <ul> <li> <p>Install <code dir="auto">@netlify/sdk@latest</code> and <code dir="auto">@netlify/netlify-plugin-netlify-extension@latest</code></p> </li> <li> <p>Update the <code dir="auto">netlify.toml</code> file in your project to include <code dir="auto">@netlify/netlify-plugin-netlify-extension</code></p> <div class="expressive-code"><link rel="stylesheet" href="/_astro/ec.cnoz8.css"><script type="module" src="/_astro/ec.8zarh.js"></script><figure class="frame has-title not-content"><figcaption class="header"><span class="title">netlify.toml</span></figcaption><pre data-language="toml"><code><div class="ec-line"><div class="code"><span style="--0:#A6ACCD">[[</span><span style="--0:#91B4D5">plugins</span><span style="--0:#A6ACCD">]]</span></div></div><div class="ec-line"><div class="code"><span style="--0:#E4F0FB">package</span><span style="--0:#A6ACCD"> = </span><span style="--0:#A6ACCD">"</span><span style="--0:#5DE4C7">@netlify/netlify-plugin-netlify-extension</span><span style="--0:#A6ACCD">"</span></div></div></code></pre><div class="copy"><button title="Copy to clipboard" data-copied="Copied!" data-code="[[plugins]]package = &#x22;@netlify/netlify-plugin-netlify-extension&#x22;"><div></div></button></div></figure></div> </li> </ul> <h2 id="2-update-files-in-the-project-root-folder">2. Update files in the project root folder</h2> <p>Next, update the <code dir="auto">package.json</code>, <code dir="auto">netlify.toml</code>, and <code dir="auto">integration.yaml</code> files in the project root folder.</p> <h3 id="update-packagejson-and-netlifytoml">Update <code dir="auto">package.json</code> and <code dir="auto">netlify.toml</code></h3> <p>In SDK v2, the <a href="/sdk/reference/commands/">SDK commands</a> have been renamed from <code dir="auto">netlify-integration</code> to <code dir="auto">netlify-extension</code>, and we’ve made the following changes:</p> <ul> <li><code dir="auto">netlify-extension build</code> does not accept a <code dir="auto">--watch</code> argument. You should use <code dir="auto">netlify-extension dev</code> as a replacement.</li> <li><code dir="auto">netlify-integration preview</code> has been removed. You should use <code dir="auto">netlify-extension dev</code> as a replacement.</li> </ul> <p>Update the <code dir="auto">package.json</code> in your extension project to update the SDK commands:</p> <div class="expressive-code"><figure class="frame has-title not-content"><figcaption class="header"><span class="title">package.json</span></figcaption><pre data-language="json"><code><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">"</span><span style="--0:#5DE4C7">scripts</span><span style="--0:#A6ACCD">"</span><span style="--0:#A6ACCD">: {</span></div></div><div class="ec-line highlight del"><div class="code"><span class="indent"> </span><span style="--0:#a9afcf">"</span><span style="--0:#E4F0FB">build</span><span style="--0:#a9afcf">"</span><span style="--0:#a9afcf">: </span><span style="--0:#a9afcf">"</span><span style="--0:#5DE4C7">netlify-integration build -a</span><span style="--0:#a9afcf">"</span><span style="--0:#a9afcf">,</span></div></div><div class="ec-line highlight del"><div class="code"><span class="indent"> </span><span style="--0:#a9afcf">"</span><span style="--0:#E4F0FB">dev</span><span style="--0:#a9afcf">"</span><span style="--0:#a9afcf">: </span><span style="--0:#a9afcf">"</span><span style="--0:#5DE4C7">netlify-integration dev -c</span><span style="--0:#a9afcf">"</span><span style="--0:#a9afcf">,</span></div></div><div class="ec-line highlight del"><div class="code"><span class="indent"> </span><span style="--0:#a9afcf">"</span><span style="--0:#E4F0FB">preview</span><span style="--0:#a9afcf">"</span><span style="--0:#a9afcf">: </span><span style="--0:#a9afcf">"</span><span style="--0:#5DE4C7">netlify-integration preview</span><span style="--0:#a9afcf">"</span></div></div><div class="ec-line highlight ins"><div class="code"><span class="indent"> </span><span style="--0:#acb1d0">"</span><span style="--0:#5DE4C7">build</span><span style="--0:#acb1d0">"</span><span style="--0:#e19fc1">:</span><span style="--0:#acb1d0"> </span><span style="--0:#acb1d0">"</span><span style="--0:#5DE4C7">netlify-extension build</span><span style="--0:#acb1d0">"</span><span style="--0:#acb1d0">,</span></div></div><div class="ec-line highlight ins"><div class="code"><span class="indent"> </span><span style="--0:#acb1d0">"</span><span style="--0:#E4F0FB">dev</span><span style="--0:#acb1d0">"</span><span style="--0:#acb1d0">: </span><span style="--0:#acb1d0">"</span><span style="--0:#5DE4C7">netlify-extension dev --open</span><span style="--0:#acb1d0">"</span><span style="--0:#acb1d0">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#A6ACCD"> </span></span><span style="--0:#A6ACCD">},</span></div></div></code></pre><div class="copy"><button title="Copy to clipboard" data-copied="Copied!" data-code=" &#x22;scripts&#x22;: { &#x22;build&#x22;: &#x22;netlify-integration build -a&#x22;, &#x22;dev&#x22;: &#x22;netlify-integration dev -c&#x22;, &#x22;preview&#x22;: &#x22;netlify-integration preview&#x22; &#x22;build&#x22;: &#x22;netlify-extension build&#x22;, &#x22;dev&#x22;: &#x22;netlify-extension dev --open&#x22;, },"><div></div></button></div></figure></div> <p>Along with the command changes, there are some other important setting changes to make in the extension’s <code dir="auto">netlify.toml</code> file:</p> <div class="expressive-code"><figure class="frame has-title not-content"><figcaption class="header"><span class="title">netlify.toml</span></figcaption><pre data-language="toml"><code><div class="ec-line"><div class="code"><span style="--0:#A6ACCD">[</span><span style="--0:#91B4D5">build</span><span style="--0:#A6ACCD">]</span></div></div><div class="ec-line highlight del"><div class="code"><span style="--0:#E4F0FB">command</span><span style="--0:#a9afcf">=</span><span style="--0:#a9afcf">"</span><span style="--0:#5DE4C7">netlify-integration build -a</span><span style="--0:#a9afcf">"</span></div></div><div class="ec-line highlight ins"><div class="code"><span style="--0:#E4F0FB">command</span><span style="--0:#acb1d0">=</span><span style="--0:#acb1d0">"</span><span style="--0:#5DE4C7">netlify-extension build -a</span><span style="--0:#acb1d0">"</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#E4F0FB">publish</span><span style="--0:#A6ACCD">=</span><span style="--0:#A6ACCD">"</span><span style="--0:#5DE4C7">.ntli/site/static</span><span style="--0:#A6ACCD">"</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#A6ACCD">[</span><span style="--0:#91B4D5">functions</span><span style="--0:#A6ACCD">]</span></div></div><div class="ec-line highlight del"><div class="code"><span style="--0:#E4F0FB">directory</span><span style="--0:#a9afcf">=</span><span style="--0:#a9afcf">"</span><span style="--0:#5DE4C7">.ntli/site/netlify/functions</span><span style="--0:#a9afcf">"</span></div></div><div class="ec-line highlight ins"><div class="code"><span style="--0:#E4F0FB">directory</span><span style="--0:#acb1d0"> = </span><span style="--0:#acb1d0">"</span><span style="--0:#5DE4C7">src/endpoints</span><span style="--0:#acb1d0">"</span></div></div><div class="ec-line highlight del"><div class="code"><span style="--0:#E4F0FB">node_bundler</span><span style="--0:#a9afcf"> = </span><span style="--0:#a9afcf">"</span><span style="--0:#5DE4C7">esbuild</span><span style="--0:#a9afcf">"</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line highlight del"><div class="code"><span style="--0:#a9afcf">[[</span><span style="--0:#92b4d5">headers</span><span style="--0:#a9afcf">]]</span></div></div><div class="ec-line highlight del"><div class="code"><span style="--0:#E4F0FB">for</span><span style="--0:#a9afcf">=</span><span style="--0:#a9afcf">"</span><span style="--0:#5DE4C7">/ui/*</span><span style="--0:#a9afcf">"</span></div></div><div class="ec-line highlight del"><div class="code"><span style="--0:#a9afcf">[</span><span style="--0:#92b4d5">headers</span><span style="--0:#a9afcf">.</span><span style="--0:#92b4d5">values</span><span style="--0:#a9afcf">]</span></div></div><div class="ec-line highlight del"><div class="code"><span style="--0:#E4F0FB">Access-Control-Allow-Origin</span><span style="--0:#a9afcf">=</span><span style="--0:#a9afcf">"</span><span style="--0:#5DE4C7">*</span><span style="--0:#a9afcf">"</span></div></div><div class="ec-line highlight del"><div class="code"><span style="--0:#E4F0FB">Access-Control-Allow-Headers</span><span style="--0:#a9afcf">=</span><span style="--0:#a9afcf">"</span><span style="--0:#5DE4C7">*</span><span style="--0:#a9afcf">"</span></div></div><div class="ec-line highlight del"><div class="code"><span style="--0:#E4F0FB">Access-Control-Allow-Methods</span><span style="--0:#a9afcf">=</span><span style="--0:#a9afcf">"</span><span style="--0:#5DE4C7">*</span><span style="--0:#a9afcf">"</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#A6ACCD">[</span><span style="--0:#91B4D5">dev</span><span style="--0:#A6ACCD">]</span></div></div><div class="ec-line highlight del"><div class="code"><span style="--0:#E4F0FB">autoLaunch</span><span style="--0:#a9afcf"> = </span><span style="--0:#5DE4C7">false</span></div></div><div class="ec-line highlight del"><div class="code"><span style="--0:#E4F0FB">functions</span><span style="--0:#a9afcf"> = </span><span style="--0:#a9afcf">"</span><span style="--0:#5DE4C7">.ntli/site/netlify/functions</span><span style="--0:#a9afcf">"</span></div></div><div class="ec-line highlight ins"><div class="code"><span style="--0:#E4F0FB">command</span><span style="--0:#acb1d0"> = </span><span style="--0:#acb1d0">"</span><span style="--0:#5DE4C7">netlify-extension dev</span><span style="--0:#acb1d0">"</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#A6ACCD">[[</span><span style="--0:#91B4D5">plugins</span><span style="--0:#A6ACCD">]]</span></div></div><div class="ec-line"><div class="code"><span style="--0:#E4F0FB">package</span><span style="--0:#A6ACCD"> = </span><span style="--0:#A6ACCD">"</span><span style="--0:#5DE4C7">@netlify/netlify-plugin-netlify-extension</span><span style="--0:#A6ACCD">"</span></div></div></code></pre><div class="copy"><button title="Copy to clipboard" data-copied="Copied!" data-code="[build]command=&#x22;netlify-integration build -a&#x22;command=&#x22;netlify-extension build -a&#x22;publish=&#x22;.ntli/site/static&#x22;[functions]directory=&#x22;.ntli/site/netlify/functions&#x22;directory = &#x22;src/endpoints&#x22;node_bundler = &#x22;esbuild&#x22;[[headers]]for=&#x22;/ui/*&#x22;[headers.values]Access-Control-Allow-Origin=&#x22;*&#x22;Access-Control-Allow-Headers=&#x22;*&#x22;Access-Control-Allow-Methods=&#x22;*&#x22;[dev]autoLaunch = falsefunctions = &#x22;.ntli/site/netlify/functions&#x22;command = &#x22;netlify-extension dev&#x22;[[plugins]]package = &#x22;@netlify/netlify-plugin-netlify-extension&#x22;"><div></div></button></div></figure></div> <p>The functions directory changes now that <a href="/sdk/get-started/migration-guide/migration-steps/#replace-addapihandler-with-endpoint-files">API Handlers are endpoints</a>, and you no longer need to set the <code dir="auto">node_bundler</code> and headers with the new extension UI.</p> <h3 id="rename-and-update-the-integrationyaml-file">Rename and update the <code dir="auto">integration.yaml</code> file</h3> <p>There are two changes to make to the configuration file:</p> <ul> <li>Rename the <code dir="auto">integration.yaml</code> file to <code dir="auto">extension.yaml</code>. If the file ends in <code dir="auto">.yml</code>, rename to <code dir="auto">extension.yml</code>.</li> <li>Remove <code dir="auto">integrationLevel</code> from the <code dir="auto">extension.yaml</code> file. All extensions are <a href="/sdk/get-started/migration-guide/overview/#extensions-are-installed-on-the-team-level-only">installed on the team level</a> automatically, so this can’t be customized anymore.</li> </ul> <h2 id="3-edit-methods-that-have-been-replaced-or-updated">3. Edit methods that have been replaced or updated</h2> <p>We’ve replaced and updated a number of methods and APIs. The following sections outline how to update your extension to reflect these changes. We have another section below for <a href="#6-update-code-for-connectors">changes specific to connectors</a>.</p> <ul> <li><a href="#import-netlifyextension-and-export--extension">Import <code dir="auto">NetlifyExtension</code> and export <code dir="auto">{ extension }</code></a></li> <li><a href="#replace-addapihandler-with-endpoint-files">Replace addApiHandler with endpoint files</a></li> <li><a href="#replace-contextprovideroauthtoken-with-contextauth">Replace <code dir="auto">context.providerOAuthToken</code> with <code dir="auto">context.auth</code></a></li> <li><a href="#replace-onenable-and-ondisable-with-endpoints">Replace <code dir="auto">onEnable</code> and <code dir="auto">onDisable</code> with endpoints</a></li> <li><a href="#replace-getsiteintegration-with-getsiteconfiguration">Replace <code dir="auto">getSiteIntegration</code> with <code dir="auto">getSiteConfiguration</code></a></li> <li><a href="#replace-updatesiteintegration-with-updatesiteconfiguration">Replace <code dir="auto">updateSiteIntegration</code> with <code dir="auto">updateSiteConfiguration</code></a></li> <li><a href="#replace-enableteamintegration-with-createteamconfiguration">Replace <code dir="auto">enableTeamIntegration</code> with <code dir="auto">createTeamConfiguration</code></a></li> <li><a href="#replace-enablesiteintegration-with-createsiteconfiguration">Replace <code dir="auto">enableSiteIntegration</code> with <code dir="auto">createSiteConfiguration</code></a></li> <li><a href="#replace-getteamintegration-with-getteamconfiguration">Replace <code dir="auto">getTeamIntegration</code> with <code dir="auto">getTeamConfiguration</code></a></li> <li><a href="#replace-updateteamintegration-with-updateteamconfiguration">Replace <code dir="auto">updateTeamIntegration</code> with <code dir="auto">updateTeamConfiguration</code></a></li> </ul> <h3 id="import-netlifyextension-and-export--extension">Import <code dir="auto">NetlifyExtension</code> and export <code dir="auto">{ extension }</code></h3> <p>In your <code dir="auto">src/index.ts</code> file, update the code to import and call <code dir="auto">NetlifyExtension</code>, and to export a valid <code dir="auto">extension</code> object.</p> <div class="expressive-code"><figure class="frame has-title not-content"><figcaption class="header"><span class="title">src/index.ts</span></figcaption><pre data-language="ts"><code><div class="ec-line highlight del"><div class="code"><span class="indent"> </span><span style="--0:#5DE4C7">import </span><span style="--0:#a9afcf">{</span><span style="--0:#5DE4C7"> </span><span style="--0:#ADD7FF">NetlifyIntegration</span><span style="--0:#5DE4C7"> </span><span style="--0:#a9afcf">}</span><span style="--0:#5DE4C7"> </span><span style="--0:#a9afcf">from</span><span style="--0:#5DE4C7"> </span><span style="--0:#a9afcf">"</span><span style="--0:#5DE4C7">@netlify/sdk</span><span style="--0:#a9afcf">"</span><span style="--0:#a9afcf">;</span></div></div><div class="ec-line highlight ins"><div class="code"><span class="indent"> </span><span style="--0:#5DE4C7">import </span><span style="--0:#acb1d0">{</span><span style="--0:#5DE4C7"> </span><span style="--0:#ADD7FF">NetlifyExtension</span><span style="--0:#5DE4C7"> </span><span style="--0:#acb1d0">}</span><span style="--0:#5DE4C7"> </span><span style="--0:#acb1d0">from</span><span style="--0:#5DE4C7"> </span><span style="--0:#acb1d0">"</span><span style="--0:#5DE4C7">@netlify/sdk</span><span style="--0:#acb1d0">"</span><span style="--0:#acb1d0">;</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line highlight del"><div class="code"><span class="indent"> </span><span style="--0:#92b4d5">const</span><span style="--0:#a9afcf"> </span><span style="--0:#E4F0FB">integration</span><span style="--0:#a9afcf"> </span><span style="--0:#92b4d5">=</span><span style="--0:#a9afcf"> </span><span style="--0:#5DE4C7">new</span><span style="--0:#a9afcf"> </span><span style="--0:#E4F0FBD0">NetlifyIntegration</span><span style="--0:#a9afcf">();</span></div></div><div class="ec-line highlight ins"><div class="code"><span class="indent"> </span><span style="--0:#94b6d6">const</span><span style="--0:#acb1d0"> </span><span style="--0:#E4F0FB">extension</span><span style="--0:#acb1d0"> </span><span style="--0:#94b6d6">=</span><span style="--0:#acb1d0"> </span><span style="--0:#5DE4C7">new</span><span style="--0:#acb1d0"> </span><span style="--0:#E4F0FBD0">NetlifyExtension</span><span style="--0:#acb1d0">();</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#8E93AF;--0fs:italic">// ... any other logic</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line highlight del"><div class="code"><span class="indent"> </span><span style="--0:#5DE4C7">export </span><span style="--0:#a9afcf">{</span><span style="--0:#5DE4C7"> </span><span style="--0:#ADD7FF">integration</span><span style="--0:#5DE4C7"> </span><span style="--0:#a9afcf">};</span></div></div><div class="ec-line highlight ins"><div class="code"><span class="indent"> </span><span style="--0:#5DE4C7">export </span><span style="--0:#acb1d0">{</span><span style="--0:#5DE4C7"> </span><span style="--0:#ADD7FF">extension</span><span style="--0:#5DE4C7"> </span><span style="--0:#acb1d0">};</span></div></div></code></pre><div class="copy"><button title="Copy to clipboard" data-copied="Copied!" data-code=" import { NetlifyIntegration } from &#x22;@netlify/sdk&#x22;; import { NetlifyExtension } from &#x22;@netlify/sdk&#x22;; const integration = new NetlifyIntegration(); const extension = new NetlifyExtension(); // ... any other logic export { integration }; export { extension };"><div></div></button></div></figure></div> <h3 id="replace-addapihandler-with-endpoint-files">Replace <code dir="auto">addApiHandler</code> with endpoint files</h3> <p>API Handlers are now called <a href="/sdk/endpoints/overview/">endpoints</a> in SDK v2. By default, they are now stored in individual files inside the <code dir="auto">src/endpoints</code> directory, and use the latest <a href="https://docs.netlify.com/functions/get-started/#write-a-function" class="external-link" rel="noopener noreferrer" target="_blank">Netlify Functions syntax</a> instead of <a href="https://docs.netlify.com/functions/lambda-compatibility/" class="external-link" rel="noopener noreferrer" target="_blank">Lambda-compatible syntax</a>.</p> <div class="expressive-code"><figure class="frame has-title not-content"><figcaption class="header"><span class="title">src/index.ts</span></figcaption><pre data-language="ts"><code><div class="ec-line highlight del"><div class="code"><span style="--0:#E4F0FB">integration</span><span style="--0:#a9afcf">.</span><span style="--0:#E4F0FBD0">addApiHandler</span><span style="--0:#a9afcf">(</span><span style="--0:#a9afcf">'</span><span style="--0:#5DE4C7">custom-name</span><span style="--0:#a9afcf">'</span><span style="--0:#a9afcf">, </span><span style="--0:#5DE4C7">async</span><span style="--0:#a9afcf"> (</span><span style="--0:#E4F0FB">event</span><span style="--0:#a9afcf">, </span><span style="--0:#E4F0FB">context</span><span style="--0:#a9afcf">) </span><span style="--0:#92b4d5">=></span><span style="--0:#a9afcf"> {</span></div></div><div class="ec-line highlight del"><div class="code"><span class="indent"> </span><span style="--0:#acb0c4;--0fs:italic">// ...logic</span></div></div><div class="ec-line highlight del"><div class="code"><span class="indent"> </span><span style="--0:#5de4c7d1">return</span><span style="--0:#a9afcf"> {</span><span style="--0:#E4F0FB"> </span><span style="--0:#ADD7FF">body</span><span style="--0:#a9afcf">:</span><span style="--0:#ADD7FF"> JSON</span><span style="--0:#a9afcf">.</span><span style="--0:#E4F0FBD0">stringify</span><span style="--0:#a9afcf">({}),</span><span style="--0:#E4F0FB"> </span><span style="--0:#ADD7FF">statusCode</span><span style="--0:#a9afcf">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#5DE4C7">200</span><span style="--0:#ADD7FF"> </span><span style="--0:#a9afcf">};</span></div></div><div class="ec-line highlight del"><div class="code"><span style="--0:#a9afcf">});</span></div></div></code></pre><div class="copy"><button title="Copy to clipboard" data-copied="Copied!" data-code="integration.addApiHandler(&#x27;custom-name&#x27;, async (event, context) => { // ...logic return { body: JSON.stringify({}), statusCode: 200 };});"><div></div></button></div></figure></div> <div class="expressive-code"><figure class="frame has-title not-content"><figcaption class="header"><span class="title">src/endpoints/custom-name.ts</span></figcaption><pre data-language="ts"><code><div class="ec-line highlight ins"><div class="code"><span style="--0:#5DE4C7">import </span><span style="--0:#acb1d0">{</span><span style="--0:#5DE4C7"> </span><span style="--0:#ADD7FF">withNetlifySDKContext</span><span style="--0:#5DE4C7"> </span><span style="--0:#acb1d0">}</span><span style="--0:#5DE4C7"> </span><span style="--0:#acb1d0">from</span><span style="--0:#5DE4C7"> </span><span style="--0:#acb1d0">"</span><span style="--0:#5DE4C7">@netlify/sdk/ui/functions</span><span style="--0:#acb1d0">"</span><span style="--0:#acb1d0">;</span></div></div><div class="ec-line highlight ins"><div class="code"> </div></div><div class="ec-line highlight ins"><div class="code"><span style="--0:#5DE4C7">export default </span><span style="--0:#E4F0FBD0">withNetlifySDKContext</span><span style="--0:#acb1d0">(</span><span style="--0:#5DE4C7">async </span><span style="--0:#acb1d0">(</span><span style="--0:#E4F0FB">req</span><span style="--0:#acb1d0">,</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">context</span><span style="--0:#acb1d0">)</span><span style="--0:#5DE4C7"> </span><span style="--0:#94b6d6">=></span><span style="--0:#5DE4C7"> </span><span style="--0:#acb1d0">{</span></div></div><div class="ec-line highlight ins"><div class="code"><span class="indent"> </span><span style="--0:#aeb2c6;--0fs:italic">// ...logic</span></div></div><div class="ec-line highlight ins"><div class="code"><span class="indent"> </span><span style="--0:#5de4c7d0">return</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">Response</span><span style="--0:#acb1d0">.</span><span style="--0:#E4F0FBD0">json</span><span style="--0:#acb1d0">({});</span></div></div><div class="ec-line highlight ins"><div class="code"><span style="--0:#acb1d0">});</span></div></div></code></pre><div class="copy"><button title="Copy to clipboard" data-copied="Copied!" data-code="import { withNetlifySDKContext } from &#x22;@netlify/sdk/ui/functions&#x22;;export default withNetlifySDKContext(async (req, context) => { // ...logic return Response.json({});});"><div></div></button></div></figure></div> <p>Note that you will need to update your endpoints from the Lambda-compatible event and response objects to the web-standard Request and Response objects.</p> <p>If you haven’t already, make sure to <a href="#2-update-files-in-the-project-root-folder">update the extension’s <code dir="auto">netlify.toml</code> file</a> to reflect the directory change. You’ll also need to update any paths for calling your endpoints, in your code or while testing locally, from <code dir="auto">/.netlify/functions/handler/your-endpoint-name</code> to <code dir="auto">/.netlify/functions/your-endpoint-name</code>.</p> <h3 id="replace-contextprovideroauthtoken-with-contextauth">Replace <code dir="auto">context.providerOAuthToken</code> with <code dir="auto">context.auth</code></h3> <p>If your extension uses OAuth and accesses the token in an API Handler, replace <code dir="auto">context.providerOAuthToken</code> with <code dir="auto">context.auth</code>.</p> <p>First make the above mentioned updates to <a href="#replace-addapihandler-with-endpoint-files">replace <code dir="auto">addApiHandler</code></a> and then update the file to use <code dir="auto">context.auth</code>.</p> <div class="expressive-code"><figure class="frame not-content"><figcaption class="header"></figcaption><pre data-language="ts"><code><div class="ec-line"><div class="code"><span style="--0:#5DE4C7">import </span><span style="--0:#A6ACCD">{</span><span style="--0:#5DE4C7"> </span><span style="--0:#ADD7FF">withNetlifySDKContext</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">}</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">from</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">"</span><span style="--0:#5DE4C7">@netlify/sdk/ui/functions</span><span style="--0:#A6ACCD">"</span><span style="--0:#A6ACCD">;</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#5DE4C7">export default </span><span style="--0:#E4F0FBD0">withNetlifySDKContext</span><span style="--0:#A6ACCD">((</span><span style="--0:#E4F0FB">req</span><span style="--0:#A6ACCD">,</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">context</span><span style="--0:#A6ACCD">)</span><span style="--0:#5DE4C7"> </span><span style="--0:#91B4D5">=></span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span></div></div><div class="ec-line highlight del"><div class="code"><span class="indent"> </span><span style="--0:#92b4d5">const</span><span style="--0:#5DE4C7"> </span><span style="--0:#a9afcf">{</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">providerOAuthToken</span><span style="--0:#5DE4C7"> </span><span style="--0:#a9afcf">}</span><span style="--0:#5DE4C7"> </span><span style="--0:#92b4d5">=</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">context</span><span style="--0:#a9afcf">;</span></div></div><div class="ec-line highlight ins"><div class="code"><span class="indent"> </span><span style="--0:#94b6d6">const</span><span style="--0:#5DE4C7"> </span><span style="--0:#acb1d0">{</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">providerToken</span><span style="--0:#5DE4C7"> </span><span style="--0:#acb1d0">}</span><span style="--0:#5DE4C7"> </span><span style="--0:#94b6d6">=</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">context</span><span style="--0:#acb1d0">.</span><span style="--0:#E4F0FB">auth</span><span style="--0:#acb1d0">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#8E93AF;--0fs:italic">// use the token to make authenticated requests to your API</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#5DE4C7C0">return</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">Response</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FBD0">json</span><span style="--0:#A6ACCD">({</span><span style="--0:#E4F0FB"> </span><span style="--0:#ADD7FF">message</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">"</span><span style="--0:#5DE4C7">Hello World</span><span style="--0:#A6ACCD">"</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">});</span></div></div><div class="ec-line"><div class="code"><span style="--0:#A6ACCD">});</span></div></div></code></pre><div class="copy"><button title="Copy to clipboard" data-copied="Copied!" data-code="import { withNetlifySDKContext } from &#x22;@netlify/sdk/ui/functions&#x22;;export default withNetlifySDKContext((req, context) => { const { providerOAuthToken } = context; const { providerToken } = context.auth; // use the token to make authenticated requests to your API return Response.json({ message: &#x22;Hello World&#x22; });});"><div></div></button></div></figure></div> <h3 id="replace-onenable-and-ondisable-with-endpoints">Replace <code dir="auto">onEnable</code> and <code dir="auto">onDisable</code> with endpoints</h3> <p>Remove the <code dir="auto">onEnable</code> and <code dir="auto">onDisable</code> methods and move your custom logic for the install and uninstall flows into new <a href="/sdk/endpoints/overview/">endpoints</a> that your <a href="/sdk/extension-ui/overview/">extension UI</a> will call. More on how to <a href="#5-replace-integration-ui-with-extension-ui">convert your integration UI to extension UI</a> and call endpoints is documented below.</p> <p>Note that <a href="/sdk/get-started/installation-flow/">extensions are installed</a> on the team level only. If your integration customized logic for site-level flows, you can specify this using <a href="/sdk/reference/classes/netlifyextensionclient/#createsiteconfiguration"><code dir="auto">createSiteConfiguration</code></a> and <a href="/sdk/reference/classes/netlifyextensionclient/#deletesiteconfiguration"><code dir="auto">deleteSiteConfiguration</code></a>.</p> <div class="expressive-code"><figure class="frame has-title not-content"><figcaption class="header"><span class="title">src/index.ts</span></figcaption><pre data-language="ts"><code><div class="ec-line highlight del"><div class="code"><span class="indent"> </span><span style="--0:#E4F0FB">integration</span><span style="--0:#a9afcf">.</span><span style="--0:#E4F0FBD0">onEnable</span><span style="--0:#a9afcf">(() </span><span style="--0:#92b4d5">=></span><span style="--0:#a9afcf"> {</span></div></div><div class="ec-line highlight del"><div class="code"><span class="indent"> </span><span style="--0:#acb0c4;--0fs:italic">// ... logic to run after the integration is enabled for a site or team</span></div></div><div class="ec-line highlight del"><div class="code"><span style="--0:#a9afcf"><span class="indent"> </span>}</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line highlight del"><div class="code"><span class="indent"> </span><span style="--0:#E4F0FB">integration</span><span style="--0:#a9afcf">.</span><span style="--0:#E4F0FBD0">onDisable</span><span style="--0:#a9afcf">(() </span><span style="--0:#92b4d5">=></span><span style="--0:#a9afcf"> {</span></div></div><div class="ec-line highlight del"><div class="code"><span class="indent"> </span><span style="--0:#acb0c4;--0fs:italic">// ... logic to run before the integration is disabled for a site or team</span></div></div><div class="ec-line highlight del"><div class="code"><span style="--0:#a9afcf"><span class="indent"> </span>}</span></div></div></code></pre><div class="copy"><button title="Copy to clipboard" data-copied="Copied!" data-code=" integration.onEnable(() => { // ... logic to run after the integration is enabled for a site or team } integration.onDisable(() => { // ... logic to run before the integration is disabled for a site or team }"><div></div></button></div></figure></div> <div class="expressive-code"><figure class="frame has-title not-content"><figcaption class="header"><span class="title">src/endpoints/after-install.ts</span></figcaption><pre data-language="ts"><code><div class="ec-line highlight ins"><div class="code"><span style="--0:#5DE4C7">import </span><span style="--0:#acb1d0">{</span><span style="--0:#5DE4C7"> </span><span style="--0:#ADD7FF">withNetlifySDKContext</span><span style="--0:#5DE4C7"> </span><span style="--0:#acb1d0">}</span><span style="--0:#5DE4C7"> </span><span style="--0:#acb1d0">from</span><span style="--0:#5DE4C7"> </span><span style="--0:#acb1d0">"</span><span style="--0:#5DE4C7">@netlify/sdk/ui/functions</span><span style="--0:#acb1d0">"</span><span style="--0:#acb1d0">;</span></div></div><div class="ec-line highlight ins"><div class="code"> </div></div><div class="ec-line highlight ins"><div class="code"><span style="--0:#5DE4C7">export default </span><span style="--0:#E4F0FBD0">withNetlifySDKContext</span><span style="--0:#acb1d0">(</span><span style="--0:#5DE4C7">async </span><span style="--0:#acb1d0">(</span><span style="--0:#E4F0FB">req</span><span style="--0:#acb1d0">,</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">context</span><span style="--0:#acb1d0">)</span><span style="--0:#5DE4C7"> </span><span style="--0:#94b6d6">=></span><span style="--0:#5DE4C7"> </span><span style="--0:#acb1d0">{</span></div></div><div class="ec-line highlight ins"><div class="code"><span class="indent"> </span><span style="--0:#aeb2c6;--0fs:italic">/* ...logic to run after the extension is installed on a team</span></div></div><div class="ec-line highlight ins"><div class="code"><span style="--0:#aeb2c6"><span class="indent"><span style="--0fs:italic"> </span></span><span style="--0fs:italic">or configured on a site */</span></span></div></div><div class="ec-line highlight ins"><div class="code"><span class="indent"> </span><span style="--0:#5de4c7d0">return</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">Response</span><span style="--0:#acb1d0">.</span><span style="--0:#E4F0FBD0">json</span><span style="--0:#acb1d0">({});</span></div></div><div class="ec-line highlight ins"><div class="code"><span style="--0:#acb1d0">});</span></div></div></code></pre><div class="copy"><button title="Copy to clipboard" data-copied="Copied!" data-code="import { withNetlifySDKContext } from &#x22;@netlify/sdk/ui/functions&#x22;;export default withNetlifySDKContext(async (req, context) => { /* ...logic to run after the extension is installed on a team or configured on a site */ return Response.json({});});"><div></div></button></div></figure></div> <div class="expressive-code"><figure class="frame has-title not-content"><figcaption class="header"><span class="title">src/endpoints/before-uninstall.ts</span></figcaption><pre data-language="ts"><code><div class="ec-line highlight ins"><div class="code"><span style="--0:#5DE4C7">import </span><span style="--0:#acb1d0">{</span><span style="--0:#5DE4C7"> </span><span style="--0:#ADD7FF">withNetlifySDKContext</span><span style="--0:#5DE4C7"> </span><span style="--0:#acb1d0">}</span><span style="--0:#5DE4C7"> </span><span style="--0:#acb1d0">from</span><span style="--0:#5DE4C7"> </span><span style="--0:#acb1d0">"</span><span style="--0:#5DE4C7">@netlify/sdk/ui/functions</span><span style="--0:#acb1d0">"</span><span style="--0:#acb1d0">;</span></div></div><div class="ec-line highlight ins"><div class="code"> </div></div><div class="ec-line highlight ins"><div class="code"><span style="--0:#5DE4C7">export default </span><span style="--0:#E4F0FBD0">withNetlifySDKContext</span><span style="--0:#acb1d0">(</span><span style="--0:#5DE4C7">async </span><span style="--0:#acb1d0">(</span><span style="--0:#E4F0FB">req</span><span style="--0:#acb1d0">,</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">context</span><span style="--0:#acb1d0">)</span><span style="--0:#5DE4C7"> </span><span style="--0:#94b6d6">=></span><span style="--0:#5DE4C7"> </span><span style="--0:#acb1d0">{</span></div></div><div class="ec-line highlight ins"><div class="code"><span class="indent"> </span><span style="--0:#aeb2c6;--0fs:italic">/* ...logic to run before the extension is uninstalled from a team</span></div></div><div class="ec-line highlight ins"><div class="code"><span style="--0:#aeb2c6"><span class="indent"><span style="--0fs:italic"> </span></span><span style="--0fs:italic">or configuration is removed from a site */</span></span></div></div><div class="ec-line highlight ins"><div class="code"><span class="indent"> </span><span style="--0:#5de4c7d0">return</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">Response</span><span style="--0:#acb1d0">.</span><span style="--0:#E4F0FBD0">json</span><span style="--0:#acb1d0">({});</span></div></div><div class="ec-line highlight ins"><div class="code"><span style="--0:#acb1d0">});</span></div></div></code></pre><div class="copy"><button title="Copy to clipboard" data-copied="Copied!" data-code="import { withNetlifySDKContext } from &#x22;@netlify/sdk/ui/functions&#x22;;export default withNetlifySDKContext(async (req, context) => { /* ...logic to run before the extension is uninstalled from a team or configuration is removed from a site */ return Response.json({});});"><div></div></button></div></figure></div> <h3 id="replace-getsiteintegration-with-getsiteconfiguration">Replace <code dir="auto">getSiteIntegration</code> with <code dir="auto">getSiteConfiguration</code></h3> <p>If you’re using <code dir="auto">getSiteIntegration</code> in your extension, replace it with <a href="/sdk/reference/classes/netlifyextensionclient/#getsiteconfiguration"><code dir="auto">getSiteConfiguration</code></a>. You will need to pass the <code dir="auto">teamId</code> in addition to the <code dir="auto">siteId</code> and add a check for <code dir="auto">configurationResponse</code>.</p> <p>Before:</p> <div class="expressive-code"><figure class="frame has-title not-content"><figcaption class="header"><span class="title">src/endpoints/get-site-config.ts</span></figcaption><pre data-language="ts"><code><div class="ec-line"><div class="code"><span style="--0:#5DE4C7">export default </span><span style="--0:#E4F0FBD0">withNetlifySDKContext</span><span style="--0:#A6ACCD">(</span><span style="--0:#5DE4C7">async </span><span style="--0:#A6ACCD">(</span><span style="--0:#E4F0FB">req</span><span style="--0:#A6ACCD">,</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">client</span><span style="--0:#A6ACCD">,</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">siteId</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">})</span><span style="--0:#5DE4C7"> </span><span style="--0:#91B4D5">=></span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">if</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">(</span><span style="--0:#E4F0FB">siteId</span><span style="--0:#A6ACCD">)</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#91B4D5">const</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">config</span><span style="--0:#5DE4C7"> </span><span style="--0:#91B4D5">=</span><span style="--0:#5DE4C7"> </span><span style="--0:#5DE4C7C0">await</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">client</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FBD0">getSiteIntegration</span><span style="--0:#A6ACCD">(</span><span style="--0:#E4F0FB">siteId</span><span style="--0:#A6ACCD">);</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#5DE4C7C0">return</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">Response</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FBD0">json</span><span style="--0:#A6ACCD">(</span><span style="--0:#E4F0FB">config</span><span style="--0:#A6ACCD">);</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#5DE4C7C0">return</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">Response</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FBD0">json</span><span style="--0:#A6ACCD">({},</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span><span style="--0:#E4F0FB"> </span><span style="--0:#ADD7FF">status</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#5DE4C7">500</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">});</span></div></div><div class="ec-line"><div class="code"><span style="--0:#A6ACCD">});</span></div></div></code></pre><div class="copy"><button title="Copy to clipboard" data-copied="Copied!" data-code="export default withNetlifySDKContext(async (req, { client, siteId }) => { if (siteId) { const config = await client.getSiteIntegration(siteId); return Response.json(config); } return Response.json({}, { status: 500 });});"><div></div></button></div></figure></div> <p>After:</p> <div class="expressive-code"><figure class="frame has-title not-content"><figcaption class="header"><span class="title">src/endpoints/get-site-config.ts</span></figcaption><pre data-language="ts"><code><div class="ec-line"><div class="code"><span style="--0:#5DE4C7">export default </span><span style="--0:#E4F0FBD0">withNetlifySDKContext</span><span style="--0:#A6ACCD">(</span><span style="--0:#5DE4C7">async </span><span style="--0:#A6ACCD">(</span><span style="--0:#E4F0FB">req</span><span style="--0:#A6ACCD">,</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">client</span><span style="--0:#A6ACCD">,</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">siteId</span><span style="--0:#A6ACCD">,</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">teamId</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">})</span><span style="--0:#5DE4C7"> </span><span style="--0:#91B4D5">=></span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">if</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">(</span><span style="--0:#E4F0FB">siteId</span><span style="--0:#5DE4C7"> </span><span style="--0:#91B4D5">&#x26;&#x26;</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">teamId</span><span style="--0:#A6ACCD">)</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#91B4D5">const</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">configurationResponse</span><span style="--0:#5DE4C7"> </span><span style="--0:#91B4D5">=</span><span style="--0:#5DE4C7"> </span><span style="--0:#5DE4C7C0">await</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">client</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FBD0">getSiteConfiguration</span><span style="--0:#A6ACCD">(</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#E4F0FB">teamId</span><span style="--0:#A6ACCD">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#E4F0FB">siteId</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">);</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">if</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">(</span><span style="--0:#E4F0FB">configurationResponse</span><span style="--0:#A6ACCD">)</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#91B4D5">const</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">config</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">}</span><span style="--0:#5DE4C7"> </span><span style="--0:#91B4D5">=</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">configurationResponse</span><span style="--0:#A6ACCD">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#5DE4C7C0">return</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">Response</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FBD0">json</span><span style="--0:#A6ACCD">(</span><span style="--0:#E4F0FB">config</span><span style="--0:#A6ACCD">);</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#5DE4C7C0">return</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">Response</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FBD0">json</span><span style="--0:#A6ACCD">({},</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span><span style="--0:#E4F0FB"> </span><span style="--0:#ADD7FF">status</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#5DE4C7">500</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">});</span></div></div><div class="ec-line"><div class="code"><span style="--0:#A6ACCD">});</span></div></div></code></pre><div class="copy"><button title="Copy to clipboard" data-copied="Copied!" data-code="export default withNetlifySDKContext(async (req, { client, siteId, teamId }) => { if (siteId &#x26;&#x26; teamId) { const configurationResponse = await client.getSiteConfiguration( teamId, siteId ); if (configurationResponse) { const { config } = configurationResponse; return Response.json(config); } } return Response.json({}, { status: 500 });});"><div></div></button></div></figure></div> <h3 id="replace-updatesiteintegration-with-updatesiteconfiguration">Replace <code dir="auto">updateSiteIntegration</code> with <code dir="auto">updateSiteConfiguration</code></h3> <p>If you’re using <code dir="auto">updateSiteIntegration</code> in your extension, replace it with <a href="/sdk/reference/classes/netlifyextensionclient/#updatesiteconfiguration"><code dir="auto">updateSiteConfiguration</code></a>. You will need to pass the <code dir="auto">teamId</code> in addition to the <code dir="auto">siteId</code>.</p> <p>Before:</p> <div class="expressive-code"><figure class="frame has-title not-content"><figcaption class="header"><span class="title">src/endpoints/update-site-config.ts</span></figcaption><pre data-language="ts"><code><div class="ec-line"><div class="code"><span style="--0:#5DE4C7">export default </span><span style="--0:#E4F0FBD0">withNetlifySDKContext</span><span style="--0:#A6ACCD">(</span><span style="--0:#5DE4C7">async </span><span style="--0:#A6ACCD">(</span><span style="--0:#E4F0FB">req</span><span style="--0:#A6ACCD">,</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">client</span><span style="--0:#A6ACCD">,</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">siteId</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">})</span><span style="--0:#5DE4C7"> </span><span style="--0:#91B4D5">=></span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">if</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">(</span><span style="--0:#E4F0FB">siteId</span><span style="--0:#5DE4C7"> </span><span style="--0:#91B4D5">&#x26;&#x26;</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">body</span><span style="--0:#A6ACCD">)</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#91B4D5">const</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span><span style="--0:#5DE4C7"> config</span><span style="--0:#A6ACCD">:</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">updatedConfig</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">}</span><span style="--0:#5DE4C7"> </span><span style="--0:#91B4D5">=</span><span style="--0:#5DE4C7"> </span><span style="--0:#ADD7FF">JSON</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FBD0">parse</span><span style="--0:#A6ACCD">(</span><span style="--0:#E4F0FB">body</span><span style="--0:#A6ACCD">);</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#91B4D5">const</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">config</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">}</span><span style="--0:#5DE4C7"> </span><span style="--0:#91B4D5">=</span><span style="--0:#5DE4C7"> </span><span style="--0:#5DE4C7C0">await</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">client</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FBD0">getSiteIntegration</span><span style="--0:#A6ACCD">(</span><span style="--0:#E4F0FB">siteId</span><span style="--0:#A6ACCD">);</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#91B4D5">const</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">newConfig</span><span style="--0:#5DE4C7"> </span><span style="--0:#91B4D5">=</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#91B4D5">...</span><span style="--0:#E4F0FB">config</span><span style="--0:#A6ACCD">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#91B4D5">...</span><span style="--0:#E4F0FB">updatedConfig</span><span style="--0:#A6ACCD">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">};</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#5DE4C7C0">await</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">client</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FBD0">updateSiteIntegration</span><span style="--0:#A6ACCD">(</span><span style="--0:#E4F0FB">siteId</span><span style="--0:#A6ACCD">,</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">newConfig</span><span style="--0:#A6ACCD">);</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#5DE4C7C0">return</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">Response</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FBD0">json</span><span style="--0:#A6ACCD">({});</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#5DE4C7C0">return</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">Response</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FBD0">json</span><span style="--0:#A6ACCD">({},</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span><span style="--0:#E4F0FB"> </span><span style="--0:#ADD7FF">status</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#5DE4C7">500</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">});</span></div></div><div class="ec-line"><div class="code"><span style="--0:#A6ACCD">});</span></div></div></code></pre><div class="copy"><button title="Copy to clipboard" data-copied="Copied!" data-code="export default withNetlifySDKContext(async (req, { client, siteId }) => { if (siteId &#x26;&#x26; body) { const { config: updatedConfig } = JSON.parse(body); const { config } = await client.getSiteIntegration(siteId); const newConfig = { ...config, ...updatedConfig, }; await client.updateSiteIntegration(siteId, newConfig); return Response.json({}); } return Response.json({}, { status: 500 });});"><div></div></button></div></figure></div> <p>After:</p> <div class="expressive-code"><figure class="frame has-title not-content"><figcaption class="header"><span class="title">src/endpoints/update-site-config.ts</span></figcaption><pre data-language="ts"><code><div class="ec-line"><div class="code"><span style="--0:#5DE4C7">export default </span><span style="--0:#E4F0FBD0">withNetlifySDKContext</span><span style="--0:#A6ACCD">(</span><span style="--0:#5DE4C7">async </span><span style="--0:#A6ACCD">(</span><span style="--0:#E4F0FB">req</span><span style="--0:#A6ACCD">,</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">client</span><span style="--0:#A6ACCD">,</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">siteId</span><span style="--0:#A6ACCD">,</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">teamId</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">})</span><span style="--0:#5DE4C7"> </span><span style="--0:#91B4D5">=></span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">if</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">(</span><span style="--0:#E4F0FB">siteId</span><span style="--0:#5DE4C7"> </span><span style="--0:#91B4D5">&#x26;&#x26;</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">body</span><span style="--0:#5DE4C7"> </span><span style="--0:#91B4D5">&#x26;&#x26;</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">teamId</span><span style="--0:#A6ACCD">)</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#91B4D5">const</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span><span style="--0:#5DE4C7"> config</span><span style="--0:#A6ACCD">:</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">updatedConfig</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">}</span><span style="--0:#5DE4C7"> </span><span style="--0:#91B4D5">=</span><span style="--0:#5DE4C7"> </span><span style="--0:#ADD7FF">JSON</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FBD0">parse</span><span style="--0:#A6ACCD">(</span><span style="--0:#E4F0FB">body</span><span style="--0:#A6ACCD">);</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#91B4D5">const</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">configurationResponse</span><span style="--0:#5DE4C7"> </span><span style="--0:#91B4D5">=</span><span style="--0:#5DE4C7"> </span><span style="--0:#5DE4C7C0">await</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">client</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FBD0">getSiteConfiguration</span><span style="--0:#A6ACCD">(</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#E4F0FB">teamId</span><span style="--0:#A6ACCD">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#E4F0FB">siteId</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">);</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">if</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">(</span><span style="--0:#E4F0FB">configurationResponse</span><span style="--0:#A6ACCD">)</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#91B4D5">const</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">config</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">}</span><span style="--0:#5DE4C7"> </span><span style="--0:#91B4D5">=</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">configurationResponse</span><span style="--0:#A6ACCD">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#91B4D5">const</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">newConfig</span><span style="--0:#5DE4C7"> </span><span style="--0:#91B4D5">=</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#91B4D5">...</span><span style="--0:#A6ACCD">(</span><span style="--0:#E4F0FB">config</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCDD2">as</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">{}),</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#91B4D5">...</span><span style="--0:#E4F0FB">updatedConfig</span><span style="--0:#A6ACCD">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">};</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#5DE4C7C0">await</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">client</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FBD0">updateSiteConfiguration</span><span style="--0:#A6ACCD">(</span><span style="--0:#E4F0FB">teamId</span><span style="--0:#A6ACCD">,</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">siteId</span><span style="--0:#A6ACCD">,</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">newConfig</span><span style="--0:#A6ACCD">);</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#5DE4C7C0">return</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">Response</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FBD0">json</span><span style="--0:#A6ACCD">({});</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#5DE4C7C0">return</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">Response</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FBD0">json</span><span style="--0:#A6ACCD">({},</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span><span style="--0:#E4F0FB"> </span><span style="--0:#ADD7FF">status</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#5DE4C7">500</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">});</span></div></div><div class="ec-line"><div class="code"><span style="--0:#A6ACCD">});</span></div></div></code></pre><div class="copy"><button title="Copy to clipboard" data-copied="Copied!" data-code="export default withNetlifySDKContext(async (req, { client, siteId, teamId }) => { if (siteId &#x26;&#x26; body &#x26;&#x26; teamId) { const { config: updatedConfig } = JSON.parse(body); const configurationResponse = await client.getSiteConfiguration( teamId, siteId ); if (configurationResponse) { const { config } = configurationResponse; const newConfig = { ...(config as {}), ...updatedConfig, }; await client.updateSiteConfiguration(teamId, siteId, newConfig); return Response.json({}); } } return Response.json({}, { status: 500 });});"><div></div></button></div></figure></div> <h3 id="replace-enableteamintegration-with-createteamconfiguration">Replace <code dir="auto">enableTeamIntegration</code> with <code dir="auto">createTeamConfiguration</code></h3> <p>If you’re using <code dir="auto">enableTeamIntegration</code> in your extension to create a team configuration, replace it with <a href="/sdk/reference/classes/netlifyextensionclient/#createteamconfiguration"><code dir="auto">createTeamConfiguration</code></a>.</p> <div class="expressive-code"><figure class="frame has-title not-content"><figcaption class="header"><span class="title">src/endpoints/create-team-config.ts</span></figcaption><pre data-language="ts"><code><div class="ec-line"><div class="code"><span style="--0:#5DE4C7">export default </span><span style="--0:#E4F0FBD0">withNetlifySDKContext</span><span style="--0:#A6ACCD">(</span><span style="--0:#5DE4C7">async </span><span style="--0:#A6ACCD">(</span><span style="--0:#E4F0FB">req</span><span style="--0:#A6ACCD">,</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">client</span><span style="--0:#A6ACCD">,</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">siteId</span><span style="--0:#A6ACCD">,</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">teamId</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">})</span><span style="--0:#5DE4C7"> </span><span style="--0:#91B4D5">=></span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">if</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">(</span><span style="--0:#E4F0FB">teamId</span><span style="--0:#5DE4C7"> </span><span style="--0:#91B4D5">&#x26;&#x26;</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">body</span><span style="--0:#A6ACCD">)</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#91B4D5">const</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">config</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">}</span><span style="--0:#5DE4C7"> </span><span style="--0:#91B4D5">=</span><span style="--0:#5DE4C7"> </span><span style="--0:#ADD7FF">JSON</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FBD0">parse</span><span style="--0:#A6ACCD">(</span><span style="--0:#E4F0FB">body</span><span style="--0:#A6ACCD">);</span></div></div><div class="ec-line highlight del"><div class="code"><span class="indent"> </span><span style="--0:#5de4c7d1">await</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">client</span><span style="--0:#a9afcf">.</span><span style="--0:#E4F0FBD0">enableTeamIntegration</span><span style="--0:#a9afcf">(</span><span style="--0:#E4F0FB">teamId</span><span style="--0:#a9afcf">,</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">config</span><span style="--0:#a9afcf">);</span></div></div><div class="ec-line highlight ins"><div class="code"><span class="indent"> </span><span style="--0:#5de4c7d0">await</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">client</span><span style="--0:#acb1d0">.</span><span style="--0:#E4F0FBD0">createTeamConfiguration</span><span style="--0:#acb1d0">(</span><span style="--0:#E4F0FB">teamId</span><span style="--0:#acb1d0">,</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">config</span><span style="--0:#acb1d0">);</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#5DE4C7C0">return</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">Response</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FBD0">json</span><span style="--0:#A6ACCD">({});</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#5DE4C7C0">return</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">Response</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FBD0">json</span><span style="--0:#A6ACCD">({},</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span><span style="--0:#E4F0FB"> </span><span style="--0:#ADD7FF">status</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#5DE4C7">500</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">});</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">});</span></div></div></code></pre><div class="copy"><button title="Copy to clipboard" data-copied="Copied!" data-code="export default withNetlifySDKContext(async (req, { client, siteId, teamId }) => { if (teamId &#x26;&#x26; body) { const { config } = JSON.parse(body); await client.enableTeamIntegration(teamId, config); await client.createTeamConfiguration(teamId, config); return Response.json({}); } return Response.json({}, { status: 500 }); });"><div></div></button></div></figure></div> <h3 id="replace-enablesiteintegration-with-createsiteconfiguration">Replace <code dir="auto">enableSiteIntegration</code> with <code dir="auto">createSiteConfiguration</code></h3> <p>If you’re using <code dir="auto">enableSiteIntegration</code> in your extension, replace it with <a href="/sdk/reference/classes/netlifyextensionclient/#createsiteconfiguration"><code dir="auto">createSiteConfiguration</code></a> and pass in the <code dir="auto">teamId</code>.</p> <div class="expressive-code"><figure class="frame has-title not-content"><figcaption class="header"><span class="title">src/endpoints/create-site-config.ts</span></figcaption><pre data-language="ts"><code><div class="ec-line"><div class="code"><span style="--0:#5DE4C7">export default </span><span style="--0:#E4F0FBD0">withNetlifySDKContext</span><span style="--0:#A6ACCD">(</span><span style="--0:#5DE4C7">async </span><span style="--0:#A6ACCD">(</span><span style="--0:#E4F0FB">req</span><span style="--0:#A6ACCD">,</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">client</span><span style="--0:#A6ACCD">,</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">siteId</span><span style="--0:#A6ACCD">,</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">teamId</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">})</span><span style="--0:#5DE4C7"> </span><span style="--0:#91B4D5">=></span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#91B4D5">const</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">body</span><span style="--0:#5DE4C7"> </span><span style="--0:#91B4D5">=</span><span style="--0:#5DE4C7"> </span><span style="--0:#5DE4C7C0">await</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">req</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FBD0">json</span><span style="--0:#A6ACCD">();</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">if</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">(</span><span style="--0:#E4F0FB">teamId</span><span style="--0:#5DE4C7"> </span><span style="--0:#91B4D5">&#x26;&#x26;</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">body</span><span style="--0:#A6ACCD">)</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#91B4D5">const</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">config</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">}</span><span style="--0:#5DE4C7"> </span><span style="--0:#91B4D5">=</span><span style="--0:#5DE4C7"> </span><span style="--0:#ADD7FF">JSON</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FBD0">parse</span><span style="--0:#A6ACCD">(</span><span style="--0:#E4F0FB">body</span><span style="--0:#A6ACCD">);</span></div></div><div class="ec-line highlight del"><div class="code"><span class="indent"> </span><span style="--0:#5de4c7d1">await</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">client</span><span style="--0:#a9afcf">.</span><span style="--0:#E4F0FBD0">enableSiteIntegration</span><span style="--0:#a9afcf">(</span><span style="--0:#E4F0FB">siteId</span><span style="--0:#a9afcf">,</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">config</span><span style="--0:#a9afcf">);</span></div></div><div class="ec-line highlight ins"><div class="code"><span class="indent"> </span><span style="--0:#5de4c7d0">await</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">client</span><span style="--0:#acb1d0">.</span><span style="--0:#E4F0FBD0">createSiteConfiguration</span><span style="--0:#acb1d0">(</span><span style="--0:#E4F0FB">teamId</span><span style="--0:#acb1d0">,</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">siteId</span><span style="--0:#acb1d0">,</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">config</span><span style="--0:#acb1d0">);</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#5DE4C7C0">return</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">Response</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FBD0">json</span><span style="--0:#A6ACCD">({});</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#5DE4C7C0">return</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">Response</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FBD0">json</span><span style="--0:#A6ACCD">({},</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span><span style="--0:#E4F0FB"> </span><span style="--0:#ADD7FF">status</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#5DE4C7">500</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">});</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">});</span></div></div></code></pre><div class="copy"><button title="Copy to clipboard" data-copied="Copied!" data-code="export default withNetlifySDKContext(async (req, { client, siteId, teamId }) => { const body = await req.json(); if (teamId &#x26;&#x26; body) { const { config } = JSON.parse(body); await client.enableSiteIntegration(siteId, config); await client.createSiteConfiguration(teamId, siteId, config); return Response.json({}); } return Response.json({}, { status: 500 }); });"><div></div></button></div></figure></div> <h3 id="replace-getteamintegration-with-getteamconfiguration">Replace <code dir="auto">getTeamIntegration</code> with <code dir="auto">getTeamConfiguration</code></h3> <p>If you’re using <code dir="auto">getTeamIntegration</code> in your extension, replace it with <a href="/sdk/reference/classes/netlifyextensionclient/#getteamconfiguration"><code dir="auto">getTeamConfiguration</code></a> and add a check for <code dir="auto">configurationResponse</code>.</p> <div class="expressive-code"><figure class="frame has-title not-content"><figcaption class="header"><span class="title">src/endpoints/get-team-config.ts</span></figcaption><pre data-language="ts"><code><div class="ec-line"><div class="code"><span style="--0:#5DE4C7">export default </span><span style="--0:#E4F0FBD0">withNetlifySDKContext</span><span style="--0:#A6ACCD">(</span><span style="--0:#5DE4C7">async </span><span style="--0:#A6ACCD">(</span><span style="--0:#E4F0FB">req</span><span style="--0:#A6ACCD">,</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">client</span><span style="--0:#A6ACCD">,</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">teamId</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">})</span><span style="--0:#5DE4C7"> </span><span style="--0:#91B4D5">=></span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">if</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">(</span><span style="--0:#E4F0FB">teamId</span><span style="--0:#A6ACCD">)</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span></div></div><div class="ec-line highlight del"><div class="code"><span class="indent"> </span><span style="--0:#92b4d5">const</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">config</span><span style="--0:#5DE4C7"> </span><span style="--0:#92b4d5">=</span><span style="--0:#5DE4C7"> </span><span style="--0:#5de4c7d1">await</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">client</span><span style="--0:#a9afcf">.</span><span style="--0:#E4F0FBD0">getTeamIntegration</span><span style="--0:#a9afcf">(</span><span style="--0:#E4F0FB">teamId</span><span style="--0:#a9afcf">);</span></div></div><div class="ec-line highlight ins"><div class="code"><span class="indent"> </span><span style="--0:#94b6d6">const</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">configurationResponse</span><span style="--0:#5DE4C7"> </span><span style="--0:#94b6d6">=</span><span style="--0:#5DE4C7"> </span><span style="--0:#5de4c7d0">await</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">client</span><span style="--0:#acb1d0">.</span><span style="--0:#E4F0FBD0">getTeamConfiguration</span><span style="--0:#acb1d0">(</span><span style="--0:#E4F0FB">teamId</span><span style="--0:#acb1d0">);</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line highlight ins"><div class="code"><span class="indent"> </span><span style="--0:#acb1d0">if</span><span style="--0:#5DE4C7"> </span><span style="--0:#acb1d0">(</span><span style="--0:#E4F0FB">configurationResponse</span><span style="--0:#acb1d0">)</span><span style="--0:#5DE4C7"> </span><span style="--0:#acb1d0">{</span></div></div><div class="ec-line highlight ins"><div class="code"><span class="indent"> </span><span style="--0:#94b6d6">const</span><span style="--0:#5DE4C7"> </span><span style="--0:#acb1d0">{</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">config</span><span style="--0:#5DE4C7"> </span><span style="--0:#acb1d0">}</span><span style="--0:#5DE4C7"> </span><span style="--0:#94b6d6">=</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">configurationResponse</span><span style="--0:#acb1d0">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#5DE4C7C0">return</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">Response</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FBD0">json</span><span style="--0:#A6ACCD">(</span><span style="--0:#E4F0FB">config</span><span style="--0:#A6ACCD">);</span></div></div><div class="ec-line highlight ins"><div class="code"><span class="indent"> </span><span style="--0:#acb1d0">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#5DE4C7C0">return</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">Response</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FBD0">json</span><span style="--0:#A6ACCD">({},</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span><span style="--0:#E4F0FB"> </span><span style="--0:#ADD7FF">status</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#5DE4C7">500</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">});</span></div></div><div class="ec-line"><div class="code"><span style="--0:#A6ACCD">});</span></div></div></code></pre><div class="copy"><button title="Copy to clipboard" data-copied="Copied!" data-code="export default withNetlifySDKContext(async (req, { client, teamId }) => { if (teamId) { const config = await client.getTeamIntegration(teamId); const configurationResponse = await client.getTeamConfiguration(teamId); if (configurationResponse) { const { config } = configurationResponse; return Response.json(config); } } return Response.json({}, { status: 500 });});"><div></div></button></div></figure></div> <h3 id="replace-updateteamintegration-with-updateteamconfiguration">Replace <code dir="auto">updateTeamIntegration</code> with <code dir="auto">updateTeamConfiguration</code></h3> <p>If you’re using <code dir="auto">updateTeamIntegration</code> in your extension, replace it with <a href="/sdk/reference/classes/netlifyextensionclient/#updateteamconfiguration"><code dir="auto">updateTeamConfiguration</code></a>, pass in the <code dir="auto">siteId</code>, and check for <code dir="auto">configurationResponse</code>.</p> <p>Your code likely also uses <code dir="auto">getTeamIntegration</code> before making the call to update, so you will also need to replace that with <code dir="auto">getTeamConfiguration</code> as noted in the <a href="#replace-getteamintegration-with-getteamconfiguration">above section</a>.</p> <div class="expressive-code"><figure class="frame has-title not-content"><figcaption class="header"><span class="title">src/endpoints/update-team-config.ts</span></figcaption><pre data-language="ts"><code><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#5DE4C7">export default </span><span style="--0:#E4F0FBD0">withNetlifySDKContext</span><span style="--0:#A6ACCD">(</span><span style="--0:#5DE4C7">async </span><span style="--0:#A6ACCD">(</span><span style="--0:#E4F0FB">req</span><span style="--0:#A6ACCD">,</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">client</span><span style="--0:#A6ACCD">,</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">siteId</span><span style="--0:#A6ACCD">,</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">teamId</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">})</span><span style="--0:#5DE4C7"> </span><span style="--0:#91B4D5">=></span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#91B4D5">const</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">body</span><span style="--0:#5DE4C7"> </span><span style="--0:#91B4D5">=</span><span style="--0:#5DE4C7"> </span><span style="--0:#5DE4C7C0">await</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">req</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FBD0">json</span><span style="--0:#A6ACCD">();</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">if</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">(</span><span style="--0:#E4F0FB">teamId</span><span style="--0:#5DE4C7"> </span><span style="--0:#91B4D5">&#x26;&#x26;</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">body</span><span style="--0:#A6ACCD">)</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#91B4D5">const</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span><span style="--0:#5DE4C7"> config</span><span style="--0:#A6ACCD">:</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">updatedConfig</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">}</span><span style="--0:#5DE4C7"> </span><span style="--0:#91B4D5">=</span><span style="--0:#5DE4C7"> </span><span style="--0:#ADD7FF">JSON</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FBD0">parse</span><span style="--0:#A6ACCD">(</span><span style="--0:#E4F0FB">body</span><span style="--0:#A6ACCD">);</span></div></div><div class="ec-line highlight del"><div class="code"><span class="indent"> </span><span style="--0:#92b4d5">const</span><span style="--0:#5DE4C7"> </span><span style="--0:#a9afcf">{</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">config</span><span style="--0:#5DE4C7"> </span><span style="--0:#a9afcf">}</span><span style="--0:#5DE4C7"> </span><span style="--0:#92b4d5">=</span><span style="--0:#5DE4C7"> </span><span style="--0:#5de4c7d1">await</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">client</span><span style="--0:#a9afcf">.</span><span style="--0:#E4F0FBD0">getTeamIntegration</span><span style="--0:#a9afcf">(</span><span style="--0:#E4F0FB">teamId</span><span style="--0:#a9afcf">);</span></div></div><div class="ec-line highlight ins"><div class="code"><span class="indent"> </span><span style="--0:#94b6d6">const</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">configurationResponse</span><span style="--0:#5DE4C7"> </span><span style="--0:#94b6d6">=</span><span style="--0:#5DE4C7"> </span><span style="--0:#5de4c7d0">await</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">client</span><span style="--0:#acb1d0">.</span><span style="--0:#E4F0FBD0">getTeamConfiguration</span><span style="--0:#acb1d0">(</span><span style="--0:#E4F0FB">teamId</span><span style="--0:#acb1d0">,</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">siteId</span><span style="--0:#acb1d0">);</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line highlight ins"><div class="code"><span class="indent"> </span><span style="--0:#acb1d0">if</span><span style="--0:#5DE4C7"> </span><span style="--0:#acb1d0">(</span><span style="--0:#E4F0FB">configurationResponse</span><span style="--0:#acb1d0">)</span><span style="--0:#5DE4C7"> </span><span style="--0:#acb1d0">{</span></div></div><div class="ec-line highlight ins"><div class="code"><span class="indent"> </span><span style="--0:#94b6d6">const</span><span style="--0:#5DE4C7"> </span><span style="--0:#acb1d0">{</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">config</span><span style="--0:#5DE4C7"> </span><span style="--0:#acb1d0">}</span><span style="--0:#5DE4C7"> </span><span style="--0:#94b6d6">=</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">configurationResponse</span><span style="--0:#acb1d0">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#91B4D5">const</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">newConfig</span><span style="--0:#5DE4C7"> </span><span style="--0:#91B4D5">=</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span></div></div><div class="ec-line highlight del"><div class="code"><span class="indent"> </span><span style="--0:#92b4d5">...</span><span style="--0:#E4F0FB">config</span><span style="--0:#a9afcf">,</span></div></div><div class="ec-line highlight ins"><div class="code"><span class="indent"> </span><span style="--0:#94b6d6">...</span><span style="--0:#acb1d0">(</span><span style="--0:#E4F0FB">config</span><span style="--0:#ADD7FF"> </span><span style="--0:#acb1d0fe">as</span><span style="--0:#ADD7FF"> </span><span style="--0:#acb1d0">{}),</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#91B4D5">...</span><span style="--0:#E4F0FB">updatedConfig</span><span style="--0:#A6ACCD">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">};</span></div></div><div class="ec-line highlight del"><div class="code"><span class="indent"> </span><span style="--0:#5de4c7d1">await</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">client</span><span style="--0:#a9afcf">.</span><span style="--0:#E4F0FBD0">updateTeamIntegration</span><span style="--0:#a9afcf">(</span><span style="--0:#E4F0FB">teamId</span><span style="--0:#a9afcf">,</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">newConfig</span><span style="--0:#a9afcf">);</span></div></div><div class="ec-line highlight ins"><div class="code"><span class="indent"> </span><span style="--0:#5de4c7d0">await</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">client</span><span style="--0:#acb1d0">.</span><span style="--0:#E4F0FBD0">updateTeamConfiguration</span><span style="--0:#acb1d0">(</span><span style="--0:#E4F0FB">teamId</span><span style="--0:#acb1d0">,</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">newConfig</span><span style="--0:#acb1d0">);</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#5DE4C7C0">return</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">Response</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FBD0">json</span><span style="--0:#A6ACCD">({});</span></div></div><div class="ec-line highlight ins"><div class="code"><span class="indent"> </span><span style="--0:#acb1d0">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#5DE4C7C0">return</span><span style="--0:#5DE4C7"> </span><span style="--0:#E4F0FB">Response</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FBD0">json</span><span style="--0:#A6ACCD">({},</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">{</span><span style="--0:#E4F0FB"> </span><span style="--0:#ADD7FF">status</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#5DE4C7">500</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">});</span></div></div><div class="ec-line"><div class="code"><span style="--0:#5DE4C7">)</span><span style="--0:#A6ACCD">;</span></div></div></code></pre><div class="copy"><button title="Copy to clipboard" data-copied="Copied!" data-code=" export default withNetlifySDKContext(async (req, { client, siteId, teamId }) => { const body = await req.json(); if (teamId &#x26;&#x26; body) { const { config: updatedConfig } = JSON.parse(body); const { config } = await client.getTeamIntegration(teamId); const configurationResponse = await client.getTeamConfiguration(teamId, siteId); if (configurationResponse) { const { config } = configurationResponse; const newConfig = { ...config, ...(config as {}), ...updatedConfig, }; await client.updateTeamIntegration(teamId, newConfig); await client.updateTeamConfiguration(teamId, newConfig); return Response.json({}); } } return Response.json({}, { status: 500 }););"><div></div></button></div></figure></div> <h2 id="4-remove-methods-and-fields-that-no-longer-exist">4. Remove methods and fields that no longer exist</h2> <p>The following methods and fields are at end of service and should be removed from your extension:</p> <ul> <li>Remove <code dir="auto">enableBuildEventHandlers</code> and <code dir="auto">disableBuildEventHandlers</code>. Build event handlers run on every site when a user installs an extension on a team. If this is undesirable behavior, refer to the <a href="/sdk/get-started/migration-guide/overview/#build-event-handlers-edge-function-injection-and-function-injection-run-on-every-site">section on the migration overview page</a> to learn how you can add a safeguard for this.</li> </ul> <h2 id="5-replace-integration-ui-with-extension-ui">5. Replace Integration UI with extension UI</h2> <p>We are excited about the brand new <a href="/sdk/extension-ui/overview/">extension UI</a> functionality and the opportunity it provides to build rich user experiences on top of the React ecosystem. However, because it is a complete replacement, migrating Integration UI to extension UI is not a straightforward change.</p> <p>To help with this migration, the SDK includes a migration helper that will add extension UI boilerplate files to your new extension.</p> <p>The following sections provide some more <a href="#whats-changed">details about the change</a>, <a href="#how-to-migrate">how to migrate</a>, and some <a href="#migrated-form-example">sample code</a>.</p> <h3 id="whats-changed">What’s changed</h3> <p>Integration UI is a custom UI framework that sends messages to the Netlify UI, communicating what UI state and interactivity the Netlify UI should set up on your extension’s behalf. Extension UI, on the other hand, allows you to write a single-page React application that Netlify renders to sandboxed iFrames in different locations within the Netlify UI.</p> <p>The way extensions work is also more flexible than before. While extensions were previously installed to sites, they are now installed once on a team and then configured on individual sites. To support this flexibility, your UI and endpoints may need to change to accommodate this change. For example, while Integration UI surfaces always modified a site, some extension UI surfaces exist to modify a team instead.</p> <p>While migrating your UI involves manual work, we hope you’ll ultimately find building on top of the React ecosystem easier and more familiar than working with a bespoke UI framework.</p> <p>For more information about all of the components and surfaces available, refer to the <a href="/sdk/reference/overview/#react-apis-for-extension-ui">extension UI reference docs</a>.</p> <h3 id="how-to-migrate">How to migrate</h3> <p>The specifics might differ depending on what you built previously but here are some rough steps for migrating to extension UI:</p> <ol> <li>Read through the <a href="/sdk/extension-ui/overview/">extension UI documentation</a> to get a sense of how it works.</li> <li>Run <code dir="auto">npm create @netlify/sdk@latest -- --uiMigration</code> to add extension UI boilerplate files to your extension.</li> <li>Modify the generated <a href="/sdk/extension-ui/add-a-new-surface/#extension-details-page">extension details</a> and <a href="/sdk/extension-ui/add-a-new-surface/#top-level-site-section">top-level site section</a> surfaces for your extension. <ul> <li>The extension details page is a new surface. If your extension offers an OAuth connection, you should add a <code dir="auto">&#x3C;ProviderAuthConnection /></code> component to your extension details page surface.</li> <li>If your extension has a connector, and you answered yes to this question during the <code dir="auto">--uiMigration</code> wizard, you should also have surfaces generated for <a href="/sdk/extension-ui/add-a-new-surface/#netlify-connect-settings">Connect</a>, <a href="/sdk/extension-ui/add-a-new-surface/#site-visual-editor-settings">the visual editor</a>, or both.</li> </ul> </li> <li>If required, move any endpoints defined using <code dir="auto">addApiHandler()</code> in your <code dir="auto">src/index.ts</code> into individual files in the <code dir="auto">src/endpoints</code> directory. For example, an API handler defined by <code dir="auto">addApiHandler("my-function", ...)</code> should be moved to <code dir="auto">src/endpoints/my-function.ts</code>. <ul> <li>You’ll also need to update your functions from <a href="https://docs.netlify.com/functions/lambda-compatibility/" class="external-link" rel="noopener noreferrer" target="_blank">Lambda-compatible syntax</a> to use the latest <a href="https://docs.netlify.com/functions/get-started/?fn-language=ts#write-a-function" class="external-link" rel="noopener noreferrer" target="_blank">Netlify Functions</a> syntax and wrap them with <code dir="auto">withNetlifySDKContext</code> to access the Netlify SDK client. Refer to the <a href="/sdk/endpoints/get-started/">endpoints documentation</a> for an example.</li> <li>If you haven’t already, make sure to <a href="#2-update-files-in-the-project-root-folder">update the extension’s <code dir="auto">netlify.toml</code> file</a> to reflect the directory change.</li> <li>You’ll also need to update any paths for calling your endpoints, in your code or while testing locally, from <code dir="auto">/.netlify/functions/handler/your-endpoint-name</code> to <code dir="auto">/.netlify/functions/your-endpoint-name</code>.</li> </ul> </li> <li>If your endpoints include any site-specific logic, make sure they are not invoked by surfaces that operate only on teams. For example, the extension details page surface.</li> <li>Finally, when you’re ready, remove your old Integration UI files including <code dir="auto">src/ui/index.ts</code>.</li> </ol> <h3 id="migrated-form-example">Migrated form example</h3> <p>Because migrating from Integration UI to extension UI involves a change of frameworks, and because each extension has a different UI experience, it’s challenging to give detailed instructions for how to migrate from one solution to the other.</p> <p>To provide a sense of how the code might change, here is an example of a form created with Integration UI and a new version created with extension UI.</p> <p>With Integration UI, a form within a card might be defined like this:</p> <div class="expressive-code"><figure class="frame not-content"><figcaption class="header"></figcaption><pre data-language="ts"><code><div class="ec-line"><div class="code"><span style="--0:#91B4D5">const</span><span style="--0:#A6ACCD"> </span><span style="--0:#E4F0FB">route</span><span style="--0:#A6ACCD"> </span><span style="--0:#91B4D5">=</span><span style="--0:#A6ACCD"> </span><span style="--0:#5DE4C7">new</span><span style="--0:#A6ACCD"> </span><span style="--0:#E4F0FBD0">SurfaceRoute</span><span style="--0:#A6ACCD">(</span><span style="--0:#A6ACCD">"</span><span style="--0:#5DE4C7">/</span><span style="--0:#A6ACCD">"</span><span style="--0:#A6ACCD">);</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#E4F0FB">route</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FBD0">addSection</span><span style="--0:#A6ACCD">(</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#A6ACCD"> </span></span><span style="--0:#A6ACCD">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#ADD7FF">id</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">"</span><span style="--0:#5DE4C7">configure-section</span><span style="--0:#A6ACCD">"</span><span style="--0:#A6ACCD">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#ADD7FF">title</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">"</span><span style="--0:#5DE4C7">Configure your Contentful space</span><span style="--0:#A6ACCD">"</span><span style="--0:#A6ACCD">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#A6ACCD"> </span></span><span style="--0:#A6ACCD">(</span><span style="--0:#E4F0FB">section</span><span style="--0:#A6ACCD">) </span><span style="--0:#91B4D5">=></span><span style="--0:#A6ACCD"> {</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#E4F0FB">section</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FBD0">addForm</span><span style="--0:#A6ACCD">(</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#A6ACCD"> </span></span><span style="--0:#A6ACCD">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#ADD7FF">id</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">"</span><span style="--0:#5DE4C7">configure-form</span><span style="--0:#A6ACCD">"</span><span style="--0:#A6ACCD">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#ADD7FF">title</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">"</span><span style="--0:#5DE4C7">Connected space</span><span style="--0:#A6ACCD">"</span><span style="--0:#A6ACCD">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#ADD7FF">onSubmit</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#5DE4C7">async</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">({</span><span style="--0:#ADD7FF"> </span><span style="--0:#E4F0FB">surfaceInputsData</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">})</span><span style="--0:#ADD7FF"> </span><span style="--0:#91B4D5">=></span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#8E93AF;--0fs:italic">// Do something with collected form data</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#A6ACCD"> </span></span><span style="--0:#A6ACCD">(</span><span style="--0:#E4F0FB">form</span><span style="--0:#A6ACCD">) </span><span style="--0:#91B4D5">=></span><span style="--0:#A6ACCD"> {</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#E4F0FB">form</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FBD0">addInputText</span><span style="--0:#A6ACCD">({</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#ADD7FF">id</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">"</span><span style="--0:#5DE4C7">username</span><span style="--0:#A6ACCD">"</span><span style="--0:#A6ACCD">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#ADD7FF">label</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">"</span><span style="--0:#5DE4C7">Password</span><span style="--0:#A6ACCD">"</span><span style="--0:#A6ACCD">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">});</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#E4F0FB">form</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FBD0">addInputPassword</span><span style="--0:#A6ACCD">({</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#ADD7FF">id</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">"</span><span style="--0:#5DE4C7">password</span><span style="--0:#A6ACCD">"</span><span style="--0:#A6ACCD">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#ADD7FF">label</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">"</span><span style="--0:#5DE4C7">Password</span><span style="--0:#A6ACCD">"</span><span style="--0:#A6ACCD">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">});</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#E4F0FB">form</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FBD0">addInputSelect</span><span style="--0:#A6ACCD">({</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#ADD7FF">id</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">"</span><span style="--0:#5DE4C7">animal</span><span style="--0:#A6ACCD">"</span><span style="--0:#A6ACCD">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#ADD7FF">label</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">"</span><span style="--0:#5DE4C7">Animal</span><span style="--0:#A6ACCD">"</span><span style="--0:#A6ACCD">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#ADD7FF">options</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">[</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">{</span><span style="--0:#E4F0FB"> </span><span style="--0:#ADD7FF">value</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">"</span><span style="--0:#5DE4C7">dog</span><span style="--0:#A6ACCD">"</span><span style="--0:#A6ACCD">,</span><span style="--0:#E4F0FB"> </span><span style="--0:#ADD7FF">label</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">"</span><span style="--0:#5DE4C7">Dog</span><span style="--0:#A6ACCD">"</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">{</span><span style="--0:#E4F0FB"> </span><span style="--0:#ADD7FF">value</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">"</span><span style="--0:#5DE4C7">cat</span><span style="--0:#A6ACCD">"</span><span style="--0:#A6ACCD">,</span><span style="--0:#E4F0FB"> </span><span style="--0:#ADD7FF">label</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">"</span><span style="--0:#5DE4C7">Cat</span><span style="--0:#A6ACCD">"</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">],</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">});</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#A6ACCD"> </span></span><span style="--0:#A6ACCD">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#A6ACCD"> </span></span><span style="--0:#A6ACCD">);</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#A6ACCD"> </span></span><span style="--0:#A6ACCD">}</span></div></div><div class="ec-line"><div class="code"><span style="--0:#A6ACCD">);</span></div></div></code></pre><div class="copy"><button title="Copy to clipboard" data-copied="Copied!" data-code="const route = new SurfaceRoute(&#x22;/&#x22;);route.addSection( { id: &#x22;configure-section&#x22;, title: &#x22;Configure your Contentful space&#x22;, }, (section) => { section.addForm( { id: &#x22;configure-form&#x22;, title: &#x22;Connected space&#x22;, onSubmit: async ({ surfaceInputsData }) => { // Do something with collected form data }, }, (form) => { form.addInputText({ id: &#x22;username&#x22;, label: &#x22;Password&#x22;, }); form.addInputPassword({ id: &#x22;password&#x22;, label: &#x22;Password&#x22;, }); form.addInputSelect({ id: &#x22;animal&#x22;, label: &#x22;Animal&#x22;, options: [ { value: &#x22;dog&#x22;, label: &#x22;Dog&#x22; }, { value: &#x22;cat&#x22;, label: &#x22;Cat&#x22; }, ], }); } ); });"><div></div></button></div></figure></div> <p>The equivalent UI in extension UI would be:</p> <div class="expressive-code"><figure class="frame not-content"><figcaption class="header"></figcaption><pre data-language="tsx"><code><div class="ec-line"><div class="code"><span style="--0:#5DE4C7">import </span><span style="--0:#A6ACCD">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#ADD7FF">Card</span><span style="--0:#A6ACCD">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#ADD7FF">CardTitle</span><span style="--0:#A6ACCD">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#ADD7FF">Form</span><span style="--0:#A6ACCD">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#ADD7FF">FormField</span><span style="--0:#A6ACCD">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#ADD7FF">FormFieldSecret</span><span style="--0:#A6ACCD">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#ADD7FF">Select</span><span style="--0:#A6ACCD">,</span></div></div><div class="ec-line"><div class="code"><span style="--0:#A6ACCD">}</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">from</span><span style="--0:#5DE4C7"> </span><span style="--0:#A6ACCD">"</span><span style="--0:#5DE4C7">@netlify/sdk/ui/react/components</span><span style="--0:#A6ACCD">"</span><span style="--0:#A6ACCD">;</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#5DE4C7">export</span><span style="--0:#A6ACCD"> </span><span style="--0:#91B4D5">const</span><span style="--0:#A6ACCD"> </span><span style="--0:#ADD7FF">SiteSettings</span><span style="--0:#A6ACCD"> </span><span style="--0:#91B4D5">=</span><span style="--0:#A6ACCD"> () </span><span style="--0:#91B4D5">=></span><span style="--0:#A6ACCD"> {</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#91B4D5">const</span><span style="--0:#A6ACCD"> </span><span style="--0:#ADD7FF">onSubmit</span><span style="--0:#A6ACCD"> </span><span style="--0:#91B4D5">=</span><span style="--0:#A6ACCD"> (</span><span style="--0:#E4F0FB">values</span><span style="--0:#A6ACCD">) </span><span style="--0:#91B4D5">=></span><span style="--0:#A6ACCD"> {</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#8E93AF;--0fs:italic">// Do something with form data</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#A6ACCD"> </span></span><span style="--0:#A6ACCD">};</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#5DE4C7C0">return</span><span style="--0:#A6ACCD"> (</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#E4F0FB">&#x3C;</span><span style="--0:#5DE4C7">Card</span><span style="--0:#E4F0FB">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#E4F0FB"> </span></span><span style="--0:#E4F0FB">&#x3C;</span><span style="--0:#5DE4C7">CardTitle</span><span style="--0:#E4F0FB">>Configure Your Extension&#x3C;/</span><span style="--0:#5DE4C7">CardTitle</span><span style="--0:#E4F0FB">></span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#E4F0FB"> </span></span><span style="--0:#E4F0FB">&#x3C;</span><span style="--0:#5DE4C7">Form</span><span style="--0:#E4F0FB"> </span><span style="--0:#91B4D5;--0fs:italic">onSubmit</span><span style="--0:#91B4D5">=</span><span style="--0:#E4F0FB">{onSubmit}></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#E4F0FB"> </span></span><span style="--0:#E4F0FB">&#x3C;</span><span style="--0:#5DE4C7">FormField</span><span style="--0:#E4F0FB"> </span><span style="--0:#91B4D5;--0fs:italic">name</span><span style="--0:#91B4D5">=</span><span style="--0:#A6ACCD">"</span><span style="--0:#5DE4C7">username</span><span style="--0:#A6ACCD">"</span><span style="--0:#E4F0FB"> </span><span style="--0:#91B4D5;--0fs:italic">label</span><span style="--0:#91B4D5">=</span><span style="--0:#A6ACCD">"</span><span style="--0:#5DE4C7">Username</span><span style="--0:#A6ACCD">"</span><span style="--0:#E4F0FB"> /></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#E4F0FB"> </span></span><span style="--0:#E4F0FB">&#x3C;</span><span style="--0:#5DE4C7">FormFieldSecret</span><span style="--0:#E4F0FB"> </span><span style="--0:#91B4D5;--0fs:italic">name</span><span style="--0:#91B4D5">=</span><span style="--0:#A6ACCD">"</span><span style="--0:#5DE4C7">password</span><span style="--0:#A6ACCD">"</span><span style="--0:#E4F0FB"> </span><span style="--0:#91B4D5;--0fs:italic">label</span><span style="--0:#91B4D5">=</span><span style="--0:#A6ACCD">"</span><span style="--0:#5DE4C7">password</span><span style="--0:#A6ACCD">"</span><span style="--0:#E4F0FB"> /></span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#E4F0FB"> </span></span><span style="--0:#E4F0FB">&#x3C;</span><span style="--0:#5DE4C7">Select</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#91B4D5;--0fs:italic">name</span><span style="--0:#91B4D5">=</span><span style="--0:#A6ACCD">"</span><span style="--0:#5DE4C7">animal</span><span style="--0:#A6ACCD">"</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#91B4D5;--0fs:italic">label</span><span style="--0:#91B4D5">=</span><span style="--0:#A6ACCD">"</span><span style="--0:#5DE4C7">Animal</span><span style="--0:#A6ACCD">"</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#91B4D5;--0fs:italic">options</span><span style="--0:#91B4D5">=</span><span style="--0:#E4F0FB">{</span><span style="--0:#A6ACCD">[</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">{</span><span style="--0:#E4F0FB"> </span><span style="--0:#ADD7FF">label</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">"</span><span style="--0:#5DE4C7">Dog</span><span style="--0:#A6ACCD">"</span><span style="--0:#A6ACCD">,</span><span style="--0:#E4F0FB"> </span><span style="--0:#ADD7FF">value</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">"</span><span style="--0:#5DE4C7">dog</span><span style="--0:#A6ACCD">"</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">{</span><span style="--0:#E4F0FB"> </span><span style="--0:#ADD7FF">label</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">"</span><span style="--0:#5DE4C7">Cat</span><span style="--0:#A6ACCD">"</span><span style="--0:#A6ACCD">,</span><span style="--0:#E4F0FB"> </span><span style="--0:#ADD7FF">value</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">"</span><span style="--0:#5DE4C7">cat</span><span style="--0:#A6ACCD">"</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">]</span><span style="--0:#E4F0FB">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#E4F0FB"> </span></span><span style="--0:#E4F0FB">/></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#E4F0FB"> </span></span><span style="--0:#E4F0FB">&#x3C;/</span><span style="--0:#5DE4C7">Form</span><span style="--0:#E4F0FB">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#E4F0FB"> </span></span><span style="--0:#E4F0FB">&#x3C;</span><span style="--0:#5DE4C7">Card</span><span style="--0:#E4F0FB">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#E4F0FB"> </span></span><span style="--0:#E4F0FB">);</span></div></div><div class="ec-line"><div class="code"><span style="--0:#E4F0FB">};</span></div></div></code></pre><div class="copy"><button title="Copy to clipboard" data-copied="Copied!" data-code="import { Card, CardTitle, Form, FormField, FormFieldSecret, Select,} from &#x22;@netlify/sdk/ui/react/components&#x22;;export const SiteSettings = () => { const onSubmit = (values) => { // Do something with form data }; return ( <Card> <CardTitle>Configure Your Extension</CardTitle> <Form onSubmit={onSubmit}> <FormField name=&#x22;username&#x22; label=&#x22;Username&#x22; /> <FormFieldSecret name=&#x22;password&#x22; label=&#x22;password&#x22; /> <Select name=&#x22;animal&#x22; label=&#x22;Animal&#x22; options={[ { label: &#x22;Dog&#x22;, value: &#x22;dog&#x22; }, { label: &#x22;Cat&#x22;, value: &#x22;cat&#x22; }, ]} /> </Form> <Card> );};"><div></div></button></div></figure></div> <h2 id="6-update-code-for-connectors">6. Update code for connectors</h2> <p>SDK v2 adds support for developing extensions for Netlify Visual Editor along with Netlify Connect. To support both features, we’ve made a few changes to the SDK that you need to apply to your extension.</p> <ul> <li><a href="#define-which-feature-the-connector-supports">Define which feature the connector supports</a></li> <li><a href="#set-autoformatgraphqltypesandfields-to-true">Set <code dir="auto">autoFormatGraphQLTypesAndFields</code> to true</a></li> <li><a href="#update-removed-connector-related-apis-and-fields">Update removed connector-related APIs and fields</a></li> <li><a href="#add-extension-ui-for-your-connector">Add extension UI for your connector</a></li> </ul> <h3 id="define-which-feature-the-connector-supports">Define which feature the connector supports</h3> <p>All connectors must specify which Netlify features it supports. It can be Connect, the visual editor, or both.</p> <div class="expressive-code"><figure class="frame not-content"><figcaption class="header"></figcaption><pre data-language="ts"><code><div class="ec-line"><div class="code"><span style="--0:#91B4D5">const</span><span style="--0:#A6ACCD"> </span><span style="--0:#E4F0FB">connector</span><span style="--0:#A6ACCD"> </span><span style="--0:#91B4D5">=</span><span style="--0:#A6ACCD"> </span><span style="--0:#E4F0FB">extension</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FBD0">addConnector</span><span style="--0:#A6ACCD">({</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#ADD7FF">typePrefix</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">'</span><span style="--0:#5DE4C7">Example</span><span style="--0:#A6ACCD">'</span><span style="--0:#A6ACCD">,</span></div></div><div class="ec-line highlight ins"><div class="code"><span class="indent"> </span><span style="--0:#ADD7FF">supports</span><span style="--0:#acb1d0">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#acb1d0">{</span></div></div><div class="ec-line highlight ins"><div class="code"><span class="indent"> </span><span style="--0:#ADD7FF">connect</span><span style="--0:#acb1d0">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#5DE4C7">true</span><span style="--0:#acb1d0">,</span><span style="--0:#E4F0FB"> </span><span style="--0:#aeb2c6;--0fs:italic">// or false if not supported</span></div></div><div class="ec-line highlight ins"><div class="code"><span class="indent"> </span><span style="--0:#ADD7FF">visualEditor</span><span style="--0:#acb1d0">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#5DE4C7">true</span><span style="--0:#acb1d0">,</span><span style="--0:#E4F0FB"> </span><span style="--0:#aeb2c6;--0fs:italic">// or false if not supported</span></div></div><div class="ec-line highlight ins"><div class="code"><span class="indent"> </span><span style="--0:#acb1d0">},</span></div></div><div class="ec-line"><div class="code"><span style="--0:#A6ACCD">});</span></div></div></code></pre><div class="copy"><button title="Copy to clipboard" data-copied="Copied!" data-code="const connector = extension.addConnector({ typePrefix: &#x27;Example&#x27;, supports: { connect: true, // or false if not supported visualEditor: true, // or false if not supported },});"><div></div></button></div></figure></div> <h3 id="set-autoformatgraphqltypesandfields-to-true">Set <code dir="auto">autoFormatGraphQLTypesAndFields</code> to <code dir="auto">true</code></h3> <p>All existing connectors should set <code dir="auto">autoFormatGraphQLTypesAndFields</code> to <code dir="auto">true</code>. Once set to <code dir="auto">true</code>, Netlify will format GraphQL field and type names to use pascal and camel case. Previously, this would happen automatically for all connectors.</p> <p>If <code dir="auto">autoFormatGraphQLTypesAndFields</code> is set to false or not defined at all, GraphQL fields like <code dir="auto">field_name</code> in the original data source will be <code dir="auto">field_name</code> in the GraphQL API. Sites that currently query a data layer’s GraphQL API will be expecting <code dir="auto">fieldName</code> instead.</p> <p>To avoid breaking API queries for your users, set the <code dir="auto">autoFormatGraphQLTypesAndFields</code> to true:</p> <div class="expressive-code"><figure class="frame not-content"><figcaption class="header"></figcaption><pre data-language="ts"><code><div class="ec-line"><div class="code"><span style="--0:#91B4D5">const</span><span style="--0:#A6ACCD"> </span><span style="--0:#E4F0FB">connector</span><span style="--0:#A6ACCD"> </span><span style="--0:#91B4D5">=</span><span style="--0:#A6ACCD"> </span><span style="--0:#E4F0FB">extension</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FBD0">addConnector</span><span style="--0:#A6ACCD">({</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#ADD7FF">typePrefix</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">'</span><span style="--0:#5DE4C7">Example</span><span style="--0:#A6ACCD">'</span><span style="--0:#A6ACCD">,</span></div></div><div class="ec-line highlight ins"><div class="code"><span class="indent"> </span><span style="--0:#ADD7FF">autoFormatGraphQLTypesAndFields</span><span style="--0:#acb1d0">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#5DE4C7">true</span><span style="--0:#acb1d0">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#ADD7FF">supports</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#ADD7FF">connect</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#5DE4C7">true</span><span style="--0:#A6ACCD">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#ADD7FF">visualEditor</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#D576A7">false</span><span style="--0:#A6ACCD">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">},</span></div></div><div class="ec-line"><div class="code"><span style="--0:#A6ACCD">});</span></div></div></code></pre><div class="copy"><button title="Copy to clipboard" data-copied="Copied!" data-code="const connector = extension.addConnector({ typePrefix: &#x27;Example&#x27;, autoFormatGraphQLTypesAndFields: true, supports: { connect: true, visualEditor: false, },});"><div></div></button></div></figure></div> <h3 id="update-removed-connector-related-apis-and-fields">Update removed connector-related APIs and fields</h3> <p>The following connector-specific API and fields are no longer available.</p> <ul> <li><a href="#remove-enableconnectors-and-disableconnectors">Remove <code dir="auto">enableConnectors</code> and <code dir="auto">disableConnectors</code></a></li> <li><a href="#replace-definenodemodel-with-definedocument">Replace <code dir="auto">define.nodeModel</code> with <code dir="auto">define.document</code></a></li> <li><a href="#replace-connectorevent-with-connectorsync">Replace <code dir="auto">connector.event</code> with <code dir="auto">connector.sync</code></a></li> <li><a href="#replace-connectordefineoptions-with-an-update-to-addconnector">Replace <code dir="auto">connector.defineOptions</code> with an update to <code dir="auto">addConnector</code></a></li> <li><a href="#replace-connectorinit-with-an-update-to-addconnector">Replace <code dir="auto">connector.init</code> with an update to <code dir="auto">addConnector</code></a></li> </ul> <h4 id="remove-enableconnectors-and-disableconnectors">Remove <code dir="auto">enableConnectors</code> and <code dir="auto">disableConnectors</code></h4> <p>Both of these methods have been removed. When a user enables an extension on a team, we automatically enable the connector for you.</p> <h4 id="replace-definenodemodel-with-definedocument">Replace <code dir="auto">define.nodeModel</code> with <code dir="auto">define.document</code></h4> <p>If your connector uses <code dir="auto">define.nodeModel</code>, that API has been replaced by <a href="/sdk/reference/classes/netlifyconnector/model/#document"><code dir="auto">define.document</code></a>.</p> <div class="expressive-code"><figure class="frame not-content"><figcaption class="header"></figcaption><pre data-language="ts"><code><div class="ec-line highlight del"><div class="code"><span style="--0:#E4F0FB">define</span><span style="--0:#a9afcf">.</span><span style="--0:#E4F0FBD0">nodeModel</span><span style="--0:#a9afcf">({</span></div></div><div class="ec-line highlight ins"><div class="code"><span style="--0:#E4F0FB">define.document(</span><span style="--0:#acb1d0">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#91B4D5">name</span><span style="--0:#A6ACCD">:</span><span style="--0:#E4F0FB"> </span><span style="--0:#A6ACCD">"</span><span style="--0:#5DE4C7">Post</span><span style="--0:#A6ACCD">"</span><span style="--0:#A6ACCD">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#91B4D5">cacheFieldName</span><span style="--0:#A6ACCD">:</span><span style="--0:#E4F0FB"> </span><span style="--0:#A6ACCD">"</span><span style="--0:#5DE4C7">updatedAt</span><span style="--0:#A6ACCD">"</span><span style="--0:#A6ACCD">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#91B4D5">fields</span><span style="--0:#A6ACCD">:</span><span style="--0:#E4F0FB"> </span><span style="--0:#A6ACCD">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#91B4D5">title</span><span style="--0:#A6ACCD">:</span><span style="--0:#E4F0FB"> </span><span style="--0:#A6ACCD">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#91B4D5">type</span><span style="--0:#A6ACCD">:</span><span style="--0:#E4F0FB"> </span><span style="--0:#A6ACCD">"</span><span style="--0:#5DE4C7">String</span><span style="--0:#A6ACCD">"</span><span style="--0:#A6ACCD">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#91B4D5">updatedAt</span><span style="--0:#A6ACCD">:</span><span style="--0:#E4F0FB"> </span><span style="--0:#A6ACCD">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#91B4D5">type</span><span style="--0:#A6ACCD">:</span><span style="--0:#E4F0FB"> </span><span style="--0:#A6ACCD">"</span><span style="--0:#5DE4C7">String</span><span style="--0:#A6ACCD">"</span><span style="--0:#A6ACCD">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#91B4D5">required</span><span style="--0:#A6ACCD">:</span><span style="--0:#E4F0FB"> </span><span style="--0:#5DE4C7">true</span><span style="--0:#A6ACCD">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">},</span></div></div><div class="ec-line"><div class="code"><span style="--0:#A6ACCD">}</span><span style="--0:#E4F0FB">);</span></div></div></code></pre><div class="copy"><button title="Copy to clipboard" data-copied="Copied!" data-code="define.nodeModel({define.document({ name: &#x22;Post&#x22;, cacheFieldName: &#x22;updatedAt&#x22;, fields: { title: { type: &#x22;String&#x22;, }, updatedAt: { type: &#x22;String&#x22;, required: true, }, },});"><div></div></button></div></figure></div> <h4 id="replace-connectorevent-with-connectorsync">Replace <code dir="auto">connector.event</code> with <code dir="auto">connector.sync</code></h4> <p>If your connector uses <code dir="auto">connector.event</code>, that API has been replaced by <a href="/sdk/reference/classes/netlifyconnector/sync/"><code dir="auto">connector.sync</code></a>.</p> <p>If your connector uses this API, you can pass a single function to <code dir="auto">connector.sync()</code> instead and use <code dir="auto">isInitialSync</code> to determine which logic to run.</p> <div class="expressive-code"><figure class="frame not-content"><figcaption class="header"></figcaption><pre data-language="ts"><code><div class="ec-line highlight del"><div class="code"><span style="--0:#E4F0FB">connector</span><span style="--0:#a9afcf">.</span><span style="--0:#E4F0FBD0">event</span><span style="--0:#a9afcf">(</span><span style="--0:#a9afcf">`</span><span style="--0:#5DE4C7">createAllNodes</span><span style="--0:#a9afcf">`</span><span style="--0:#a9afcf">, </span><span style="--0:#E4F0FB">customSyncAllDataFn</span><span style="--0:#a9afcf">);</span></div></div><div class="ec-line highlight del"><div class="code"><span style="--0:#E4F0FB">connector</span><span style="--0:#a9afcf">.</span><span style="--0:#E4F0FBD0">event</span><span style="--0:#a9afcf">(</span><span style="--0:#a9afcf">`</span><span style="--0:#5DE4C7">updateNodes</span><span style="--0:#a9afcf">`</span><span style="--0:#a9afcf">, </span><span style="--0:#E4F0FB">customSyncChangedDataFn</span><span style="--0:#a9afcf">);</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line highlight ins"><div class="code"><span style="--0:#E4F0FB">connector</span><span style="--0:#acb1d0">.</span><span style="--0:#E4F0FBD0">sync</span><span style="--0:#acb1d0">(({ </span><span style="--0:#E4F0FB">isInitialSync</span><span style="--0:#acb1d0">, </span><span style="--0:#E4F0FB">models</span><span style="--0:#acb1d0"> }) </span><span style="--0:#94b6d6">=></span><span style="--0:#acb1d0"> {</span></div></div><div class="ec-line highlight ins"><div class="code"><span style="--0:#acb1d0"><span class="indent"> </span>if (</span><span style="--0:#E4F0FB">isInitialSync</span><span style="--0:#acb1d0">) {</span></div></div><div class="ec-line highlight ins"><div class="code"><span class="indent"> </span><span style="--0:#5de4c7d0">return</span><span style="--0:#acb1d0"> </span><span style="--0:#E4F0FBD0">customSyncAllDataFn</span><span style="--0:#acb1d0">(</span><span style="--0:#E4F0FB">models</span><span style="--0:#acb1d0">);</span></div></div><div class="ec-line highlight ins"><div class="code"><span style="--0:#acb1d0"><span class="indent"> </span>} else {</span></div></div><div class="ec-line highlight ins"><div class="code"><span class="indent"> </span><span style="--0:#5de4c7d0">return</span><span style="--0:#acb1d0"> </span><span style="--0:#E4F0FBD0">customSyncChangedDataFn</span><span style="--0:#acb1d0">(</span><span style="--0:#E4F0FB">models</span><span style="--0:#acb1d0">);</span></div></div><div class="ec-line highlight ins"><div class="code"><span style="--0:#acb1d0"><span class="indent"> </span>}</span></div></div><div class="ec-line highlight ins"><div class="code"><span style="--0:#acb1d0">});</span></div></div></code></pre><div class="copy"><button title="Copy to clipboard" data-copied="Copied!" data-code="connector.event(&#x60;createAllNodes&#x60;, customSyncAllDataFn);connector.event(&#x60;updateNodes&#x60;, customSyncChangedDataFn);connector.sync(({ isInitialSync, models }) => { if (isInitialSync) { return customSyncAllDataFn(models); } else { return customSyncChangedDataFn(models); }});"><div></div></button></div></figure></div> <p>If you previously set <code dir="auto">connector.event('updateNodes', false)</code> to ensure every sync is a full data sync (with no caching), you need to configure your connector with <code dir="auto">deltaSync</code> set to false. This will <a href="/sdk/connectors/develop/sync-data/#if-you-cant-cache-data">disable caching</a> between data syncs:</p> <div class="expressive-code"><figure class="frame not-content"><figcaption class="header"></figcaption><pre data-language="ts"><code><div class="ec-line"><div class="code"><span style="--0:#E4F0FB">extension</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FBD0">addConnector</span><span style="--0:#A6ACCD">({</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#ADD7FF">supports</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#ADD7FF">connect</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#5DE4C7">true</span><span style="--0:#A6ACCD">,</span></div></div><div class="ec-line highlight ins"><div class="code"><span class="indent"> </span><span style="--0:#ADD7FF">deltaSync</span><span style="--0:#acb1d0">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#e19fc1">false</span><span style="--0:#acb1d0">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">},</span></div></div><div class="ec-line"><div class="code"><span style="--0:#A6ACCD">});</span></div></div></code></pre><div class="copy"><button title="Copy to clipboard" data-copied="Copied!" data-code="extension.addConnector({ supports: { connect: true, deltaSync: false, },});"><div></div></button></div></figure></div> <h4 id="replace-connectordefineoptions-with-an-update-to-addconnector">Replace <code dir="auto">connector.defineOptions</code> with an update to <code dir="auto">addConnector</code></h4> <p>Update your extension to remove <code dir="auto">connector.defineOptions</code> and instead define options in <a href="/sdk/reference/classes/netlifyextension/#addconnector"><code dir="auto">extension.addConnector</code></a>:</p> <p>As part of the migration, you will also need to <a href="#add-extension-ui-for-your-connector">add extension UI</a> for your connector and you will be able to remove the <code dir="auto">.meta</code> properties for each of these options then. For now, you can leave them in for reference while you build your extension UI.</p> <div class="expressive-code"><figure class="frame not-content"><figcaption class="header"></figcaption><pre data-language="ts"><code><div class="ec-line highlight del"><div class="code"><span class="indent"> </span><span style="--0:#E4F0FB">connector</span><span style="--0:#a9afcf">.</span><span style="--0:#E4F0FBD0">defineOptions</span><span style="--0:#a9afcf">(({ </span><span style="--0:#E4F0FB">zod</span><span style="--0:#a9afcf"> }) </span><span style="--0:#92b4d5">=></span><span style="--0:#a9afcf"> {</span></div></div><div class="ec-line highlight ins"><div class="code"><span class="indent"> </span><span style="--0:#E4F0FB">extension</span><span style="--0:#acb1d0">.</span><span style="--0:#E4F0FBD0">addConnector</span><span style="--0:#acb1d0">({</span></div></div><div class="ec-line highlight ins"><div class="code"><span class="indent"> </span><span style="--0:#ADD7FF">defineOptions</span><span style="--0:#acb1d0">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#acb1d0">({</span><span style="--0:#ADD7FF"> </span><span style="--0:#E4F0FB">zod</span><span style="--0:#ADD7FF"> </span><span style="--0:#acb1d0">})</span><span style="--0:#ADD7FF"> </span><span style="--0:#94b6d6">=></span><span style="--0:#ADD7FF"> </span><span style="--0:#acb1d0">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#5DE4C7C0">return</span><span style="--0:#ADD7FF"> </span><span style="--0:#E4F0FB">zod</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FBD0">object</span><span style="--0:#A6ACCD">({</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#ADD7FF">apiToken</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#E4F0FB">zod</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FBD0">string</span><span style="--0:#A6ACCD">().</span><span style="--0:#E4F0FBD0">meta</span><span style="--0:#A6ACCD">({</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#ADD7FF">label</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">"</span><span style="--0:#5DE4C7">API token</span><span style="--0:#A6ACCD">"</span><span style="--0:#A6ACCD">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#ADD7FF">helpText</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">"</span><span style="--0:#5DE4C7">The delivery API token for your environment</span><span style="--0:#A6ACCD">"</span><span style="--0:#A6ACCD">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#ADD7FF">secret</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#5DE4C7">true</span><span style="--0:#A6ACCD">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">}),</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#ADD7FF">pageLimit</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#E4F0FB">zod</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FBD0">string</span><span style="--0:#A6ACCD">().</span><span style="--0:#E4F0FBD0">optional</span><span style="--0:#A6ACCD">().</span><span style="--0:#E4F0FBD0">meta</span><span style="--0:#A6ACCD">({</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#ADD7FF">label</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">"</span><span style="--0:#5DE4C7">Page limit</span><span style="--0:#A6ACCD">"</span><span style="--0:#A6ACCD">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#ADD7FF">helpText</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">"</span><span style="--0:#5DE4C7">The number of entries to fetch per page when syncing data</span><span style="--0:#A6ACCD">"</span><span style="--0:#A6ACCD">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">}),</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">});</span></div></div><div class="ec-line highlight ins"><div class="code"><span class="indent"> </span><span style="--0:#acb1d0">}</span></div></div><div class="ec-line"><div class="code"><span style="--0:#A6ACCD">});</span></div></div></code></pre><div class="copy"><button title="Copy to clipboard" data-copied="Copied!" data-code=" connector.defineOptions(({ zod }) => { extension.addConnector({ defineOptions: ({ zod }) => { return zod.object({ apiToken: zod.string().meta({ label: &#x22;API token&#x22;, helpText: &#x22;The delivery API token for your environment&#x22;, secret: true, }), pageLimit: zod.string().optional().meta({ label: &#x22;Page limit&#x22;, helpText: &#x22;The number of entries to fetch per page when syncing data&#x22;, }), }); }});"><div></div></button></div></figure></div> <h4 id="replace-connectorinit-with-an-update-to-addconnector">Replace <code dir="auto">connector.init</code> with an update to <code dir="auto">addConnector</code></h4> <p>Update your extension to remove <code dir="auto">connector.init</code> and instead define the initial state in <a href="/sdk/reference/classes/netlifyextension/#addconnector"><code dir="auto">extension.addConnector</code></a>:</p> <div class="expressive-code"><figure class="frame not-content"><figcaption class="header"></figcaption><pre data-language="ts"><code><div class="ec-line highlight del"><div class="code"><span class="indent"> </span><span style="--0:#E4F0FB">connector</span><span style="--0:#a9afcf">.</span><span style="--0:#E4F0FBD0">init</span><span style="--0:#a9afcf">(({ </span><span style="--0:#E4F0FB">options</span><span style="--0:#a9afcf"> }) </span><span style="--0:#92b4d5">=></span><span style="--0:#a9afcf"> {</span></div></div><div class="ec-line highlight ins"><div class="code"><span class="indent"> </span><span style="--0:#E4F0FB">extension</span><span style="--0:#acb1d0">.</span><span style="--0:#E4F0FBD0">addConnector</span><span style="--0:#acb1d0">({</span></div></div><div class="ec-line highlight ins"><div class="code"><span class="indent"> </span><span style="--0:#ADD7FF">initState</span><span style="--0:#acb1d0">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#acb1d0">({</span><span style="--0:#ADD7FF"> </span><span style="--0:#E4F0FB">options</span><span style="--0:#ADD7FF"> </span><span style="--0:#acb1d0">})</span><span style="--0:#ADD7FF"> </span><span style="--0:#94b6d6">=></span><span style="--0:#ADD7FF"> </span><span style="--0:#acb1d0">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#91B4D5">const</span><span style="--0:#ADD7FF"> </span><span style="--0:#E4F0FB">apiClient</span><span style="--0:#ADD7FF"> </span><span style="--0:#91B4D5">=</span><span style="--0:#ADD7FF"> </span><span style="--0:#5DE4C7">new</span><span style="--0:#ADD7FF"> </span><span style="--0:#E4F0FBD0">CustomCMSAPIClient</span><span style="--0:#A6ACCD">({</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#ADD7FF">url</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#E4F0FB">options</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FB">apiURL</span><span style="--0:#A6ACCD">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#ADD7FF">token</span><span style="--0:#A6ACCD">:</span><span style="--0:#ADD7FF"> </span><span style="--0:#E4F0FB">options</span><span style="--0:#A6ACCD">.</span><span style="--0:#E4F0FB">apiToken</span><span style="--0:#A6ACCD">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">});</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#5DE4C7C0">return</span><span style="--0:#ADD7FF"> </span><span style="--0:#A6ACCD">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#E4F0FB"> </span></span><span style="--0:#E4F0FB">apiClient</span><span style="--0:#ADD7FF"> </span><span style="--0:#8E93AF;--0fs:italic">// this will be available as state.apiClient in other connector APIs</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A6ACCD">};</span></div></div><div class="ec-line highlight ins"><div class="code"><span class="indent"> </span><span style="--0:#acb1d0">}</span></div></div><div class="ec-line"><div class="code"><span style="--0:#A6ACCD">});</span></div></div></code></pre><div class="copy"><button title="Copy to clipboard" data-copied="Copied!" data-code=" connector.init(({ options }) => { extension.addConnector({ initState: ({ options }) => { const apiClient = new CustomCMSAPIClient({ url: options.apiURL, token: options.apiToken, }); return { apiClient // this will be available as state.apiClient in other connector APIs }; }});"><div></div></button></div></figure></div> <h3 id="add-extension-ui-for-your-connector">Add extension UI for your connector</h3> <p>With SDK v2, connectors must include code to add extension UI that we will render in the Netlify UI for Connect users — this is in addition to <a href="/sdk/get-started/migration-guide/migration-steps/#replace-connectordefineoptions-with-an-update-to-addconnector">defining configuration options</a> in the extension itself.</p> <p>To add extension UI for your connector, follow these steps:</p> <ol> <li>Read through the <a href="/sdk/extension-ui/overview/">extension UI documentation</a> to get a sense of how it works.</li> <li>Run <code dir="auto">npm create @netlify/sdk@latest -- --uiMigration</code> to add extension UI boilerplate files to your extension. When you receive the prompt <code dir="auto">Does your extension have a connector?</code>, make sure you specify yes and the boilerplate will include a surface for <a href="/sdk/extension-ui/add-a-new-surface/#netlify-connect-settings">Connect</a>.</li> <li>Update the boilerplate files to create a configuration form to display for users in Connect when they add a data source using your extension. The fields should match what you defined as configuration options. Refer to the <a href="/sdk/extension-ui/add-a-new-surface/#add-a-new-surface">add a surface</a> doc for an example of a form you can add.</li> <li>Add an endpoint to handle the form submission using <a href="/sdk/reference/classes/netlifyextensionclient/#createconnectconfiguration"><code dir="auto">createConnectConfiguration</code></a>.</li> </ol> <p>You can preview the form while you work by following the instructions on how to <a href="/sdk/extension-ui/develop-locally/">develop extension UI locally</a>.</p> <p>After you add extension UI for your connector, you can remove any <code dir="auto">meta</code> properties <a href="/sdk/get-started/migration-guide/migration-steps/#replace-connectordefineoptions-with-an-update-to-addconnector">on the options defined using <code dir="auto">extension.addConnector</code></a>. Note that leaving them in won’t result in errors.</p> <h2 id="7-publish-a-private-extension-to-test-in-production">7. Publish a private extension to test in production</h2> <p>Once you’re ready, you can publish a temporary private extension to test in production.</p> <h3 id="add-a-detailsmd-file-to-your-root-folder-with-information-for-your-user">Add a <code dir="auto">details.md</code> file to your root folder with information for your user</h3> <p>Follow the updated details on how to <a href="/sdk/publish/publish-extensions/#prepare-your-extension">prepare your extension</a> for publishing, and add a <code dir="auto">details.md</code> to the root of your project to provide <a href="/sdk/publish/publish-extensions/#documentation">in-app documentation</a>. You’ll be able to preview the rendered documentation in the Netlify UI once you publish the private extension.</p> <h3 id="publish-a-private-extension">Publish a private extension</h3> <p>Follow the steps to <a href="/sdk/publish/publish-extensions/#publish-a-private-extension">publish a private extension</a> using <a href="#0-prepare-to-migrate">the temporary site</a> you set up for your migration branch.</p> <h3 id="test-your-private-extension">Test your private extension</h3> <p>Once published, you can install the extension on your team and test.</p> <ol> <li>In the Netlify UI, navigate to the <strong>Extensions</strong> section for your team.</li> <li>Select <strong>Created by your team</strong> and find your private extension in the list.</li> <li>Select the extension and then select <strong>Install</strong> on the details page.</li> </ol> <h2 id="8-replace-your-published-integration-with-the-new-extension">8. Replace your published integration with the new extension</h2> <p>Once you’re ready to replace your published integration with your new extension, complete the following steps:</p> <ol> <li>Merge your <a href="#0-prepare-to-migrate">temporary extension migration branch</a> into the production branch that contains the code for your published integration.</li> <li>Make sure this triggers a new production deploy.</li> <li>Once the deploy is published, your old integration will be replaced by your newly migrated extension. The new extension will be available to all teams that have it installed. Depending on what your extension does, users may need to rebuild and redeploy their sites to run the new extension.</li> <li>To avoid confusion, we recommend deleting the temporary private extension and temporary site you set up for your migration branch. You will need to uninstall the extension from any sites that you tested it with before you can delete the extension and the site.</li> </ol> <h2 id="contact-us-for-support">Contact us for support</h2> <p>If you have questions or run into issues while migrating, please contact us <a href="https://www.netlify.com/support/" class="external-link" rel="noopener noreferrer" target="_blank">through Netlify support</a> or through the <a href="https://www.netlify.com/partners/technology/" class="external-link" rel="noopener noreferrer" target="_blank">technology partner program</a>.</p> <div class="not-content astro-77rygnu7"> <form class='astro-77rygnu7' method='POST' name='feedback'> <div class="feedback astro-77rygnu7"> <div class="astro-77rygnu7"> <h4 class="astro-77rygnu7">Did you find this doc useful?</h4> <p class="astro-77rygnu7">Your feedback helps us improve our docs.</p> </div> <div class="votes astro-77rygnu7"> <input type="radio" name="vote" value="upvote" id="upvote" class="astro-77rygnu7"> <label class="vote-button astro-77rygnu7" for="upvote"><svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" aria-hidden="true" id="svg-upvote"> <g fill="none" fill-rule="evenodd"> <circle cx="32" cy="32" r="32" fill="none" fill-rule="nonzero"></circle> <g stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="M40 29h-7.645l1.473-3.889c.377-.996.042-2.135-.803-2.73-.963-.679-2.263-.427-2.936.569L26 29v9a4 4 0 0 0 4 4h6.517c1.51 0 2.893-.852 3.573-2.203L42 36v-5a2 2 0 0 0-2-2zM22 29v12"></path> </g> </g> </svg> </label> <input type="radio" name="vote" value="downvote" id="downvote" class="astro-77rygnu7"> <label class="vote-button astro-77rygnu7" for="downvote"><svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" aria-hidden="true" id="svg-downvote"> <g fill="none" fill-rule="evenodd"> <circle cx="32" cy="32" r="32"></circle> <g stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"> <path d="M23 35h7.645l-1.473 3.889c-.377.996-.042 2.135.803 2.73.963.679 2.263.427 2.936-.569l4.09-6.05v-9a4 4 0 0 0-4-4h-6.518c-1.51 0-2.893.852-3.573 2.202L21 28v5a2 2 0 0 0 2 2zM41 35V23"></path> </g> </g> </svg> </label> <input type="radio" name="vote" value="none" id="none" checked class="astro-77rygnu7"> </div> </div> <input type="hidden" name="form-name" value="feedback" class="astro-77rygnu7"> <input type="hidden" name="path" value="/sdk/get-started/migration-guide/migration-steps/" class="astro-77rygnu7"> <textarea name="feedback" placeholder="What else would you like to tell us about this doc?" class="astro-77rygnu7"></textarea> <p class="hidden astro-77rygnu7"> <label class="astro-77rygnu7"> Don’t fill this out if you’re human: <input name="bot-field" class="astro-77rygnu7"> </label> </p> <button class="form-submit astro-77rygnu7" type="submit" disabled>Send</button> </form> <div class="success-message astro-77rygnu7"> <h4 class="astro-77rygnu7">Got it!</h4> <p class="astro-77rygnu7">Your feedback helps us improve our docs.</p> </div> </div> <footer class="astro-sz7xmlte"> <nav aria-label="Footer navigation" class="astro-sz7xmlte"> <ul class="footer_nav astro-sz7xmlte"> <li class="astro-sz7xmlte"> <a href="https://netlify.com/" class="astro-sz7xmlte">Netlify</a> </li> <li class="astro-sz7xmlte"> <a href="https://netlify.com/careers/" class="astro-sz7xmlte">Careers</a> </li> <li class="astro-sz7xmlte"> <a href="https://netlify.com/blog/" class="astro-sz7xmlte">Blog</a> </li> <li class="astro-sz7xmlte"> <a href="https://www.netlify.com/legal/terms-of-use/" class="astro-sz7xmlte">Terms</a> </li> <li class="astro-sz7xmlte"> <a href="https://www.netlify.com/privacy/" class="astro-sz7xmlte">Privacy</a> </li> </ul> </nav> <p class="footer_copyright astro-sz7xmlte">© 2023 Netlify</p> </footer> <script type="astro-raw"> <noscript> <iframe src="https://www.googletagmanager.com/ns.html?id=GTM-NMKKF2M" height="0" width="0" style="display:none;visibility:hidden" ></iframe> </noscript>; </script> </div> <footer class="sl-flex astro-vcdq3p2d"> <div class="meta sl-flex astro-vcdq3p2d"> </div> <div class="pagination-links astro-nxbj5azm" dir="ltr"> <a href="/sdk/get-started/migration-guide/overview/" rel="prev" class="astro-nxbj5azm"> <svg aria-hidden="true" class="astro-nxbj5azm astro-bg6azcwr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.5rem;"><path d="M17 11H9.41l3.3-3.29a1.004 1.004 0 1 0-1.42-1.42l-5 5a1 1 0 0 0-.21.33 1 1 0 0 0 0 .76 1 1 0 0 0 .21.33l5 5a1.002 1.002 0 0 0 1.639-.325 1 1 0 0 0-.219-1.095L9.41 13H17a1 1 0 0 0 0-2Z"/></svg> <span class="astro-nxbj5azm"> Previous <br class="astro-nxbj5azm"> <span class="link-title astro-nxbj5azm">Migration guide overview</span> </span> </a> <a href="/sdk/connectors/overview/" rel="next" class="astro-nxbj5azm"> <svg aria-hidden="true" class="astro-nxbj5azm astro-bg6azcwr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.5rem;"><path d="M17.92 11.62a1.001 1.001 0 0 0-.21-.33l-5-5a1.003 1.003 0 1 0-1.42 1.42l3.3 3.29H7a1 1 0 0 0 0 2h7.59l-3.3 3.29a1.002 1.002 0 0 0 .325 1.639 1 1 0 0 0 1.095-.219l5-5a1 1 0 0 0 .21-.33 1 1 0 0 0 0-.76Z"/></svg> <span class="astro-nxbj5azm"> Next <br class="astro-nxbj5azm"> <span class="link-title astro-nxbj5azm">Overview</span> </span> </a> </div> </footer> </div> </div> </main> </div> </div> </div> </div> <script async id="netlify-rum-container" src="/.netlify/scripts/rum" data-netlify-rum-site-id="35ffcf76-cab5-463d-a2e5-8983dba16a56" data-netlify-deploy-branch="main" data-netlify-deploy-context="production" data-netlify-cwv-token="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzaXRlX2lkIjoiMzVmZmNmNzYtY2FiNS00NjNkLWEyZTUtODk4M2RiYTE2YTU2IiwiYWNjb3VudF9pZCI6IjU4ZGE4ODkzZDY4NjVkMzVjOTJhNzJiOCIsImRlcGxveV9pZCI6IjY3NDliMDU3YWE4ODIzMDAwODAyMGU4ZCIsImlzc3VlciI6Im5mc2VydmVyIn0.XFPrMAf4IziGBukjtKWJlDIXVjX8qM9cObB0mmg3ANo"></script></body></html>

Pages: 1 2 3 4 5 6 7 8 9 10