Tạo ứng dụng ChatGPT Interactive Build an Interactive ChatGPT App បង្កើតកម្មវិធី ChatGPT អន្តរកម្ម
Hướng dẫn chi tiết đồng bộ từ docs Cloudflare — mỗi section có backlink tới đúng vị trí trên trang gốc. Detailed guide synced from Cloudflare docs — each section links to the matching anchor on the official page. មគ្គុទ្ទេសក៍លម្អិតធ្វើសមកាលពី docs Cloudflare — ផ្នែកនីមួយៗមានតំណទៅទីតាំងត្រូវគ្នានៅទំព័រផ្លូវការ។
← Danh mục ← Catalog ← បញ្ជីGiải thích nhanh Quick context បរិបទរហ័ស
Tutorial đa lĩnh vực — kết hợp nhiều sản phẩm Cloudflare. Tutorial «Xây dựng Interactive ChatGPT App» giúp bạn làm quen luồng triển khai thật — phù hợp đọc trước khi mở tài liệu gốc tiếng Anh. Đọc phần tóm tắt và lưu ý trước — sau đó mở docs gốc để copy lệnh và cấu hình chi tiết.
<!DOCTYPE html><html lang="en" dir="ltr" data-theme="dark" data-has-toc data-has-sidebar class="astro-nezwzdd7"> <head><script type="module" src="/_astro/Head.astro_astro_type_script_index_0_lang.DzFUDi6m.js"></script> <script type="module" src="/_astro/Head.astro_astro_type_script_index_1_lang.DLffOXbo.js"></script> <script type="module" src="/_astro/Head.astro_astro_type_script_index_2_lang.DdMWwAGS.js"></script> <script type="module" src="/_astro/Head.astro_astro_type_script_index_3_lang.DibilYbp.js"></script> <script type="module" src="/_astro/Head.astro_astro_type_script_index_4_lang.TkaWOEUf.js"></script> <meta charset="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><title>Build an Interactive ChatGPT App · Cloudflare Workers docs</title><link rel="canonical" href="https://developers.cloudflare.com/workers/demos/chatgpt-app/"/><link rel="sitemap" href="/sitemap-index.xml"/><link rel="shortcut icon" href="/favicon.png" type="image/png"/><meta name="generator" content="Astro v6.4.4"/><meta name="generator" content="Starlight v0.39.3"/><meta property="og:title" content="Build an Interactive ChatGPT App"/><meta property="og:type" content="article"/><meta property="og:url" content="https://developers.cloudflare.com/workers/demos/chatgpt-app/"/><meta property="og:locale" content="en"/><meta property="og:description" content="Build and deploy an interactive ChatGPT App on Cloudflare Workers with real-time multiplayer state using MCP."/><meta property="og:site_name" content="Cloudflare Docs"/><meta name="twitter:card" content="summary_large_image"/><meta name="description" content="Build and deploy an interactive ChatGPT App on Cloudflare Workers with real-time multiplayer state using MCP."/><meta name="twitter:site" content="@cloudflare"/><meta name="pcx_content_group" content="Developer platform"/><link rel="alternate" type="text/markdown" href="https://developers.cloudflare.com/workers/demos/chatgpt-app/index.md"/><meta property="og:title" content="Build an Interactive ChatGPT App · Cloudflare Workers docs"/><meta name="pcx_product" content="Workers"/><meta name="algolia_product_filter" content="Workers"/><meta name="pcx_content_type" content="Tutorial"/><meta name="algolia_content_type" content="Tutorial"/><meta name="pcx_additional_products" content="Agents"/><meta name="pcx_last_modified" content="7"/><meta name="pcx_last_reviewed" content="215"/><meta property="image" content="https://developers.cloudflare.com/dev-products-preview.png"/><meta property="og:image" content="https://developers.cloudflare.com/dev-products-preview.png"/><meta property="twitter:image" content="https://developers.cloudflare.com/dev-products-preview.png"/><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-r7kprdcr" 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-r7kprdcr" 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-r7kprdcr" 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/print.DNXP8c50.css" media="print"><link rel="stylesheet" href="/_astro/Page.DZC6j93Z.css"> <link rel="stylesheet" href="/_astro/agent-setup.Xetiu_za.css"> <link rel="stylesheet" href="/_astro/Code.BFuFJYv4.css"> <style>.hero:where(.astro-opidluyl){display:grid;align-items:center;gap:1rem;padding-bottom:1rem}.hero:where(.astro-opidluyl)>img:where(.astro-opidluyl),.hero:where(.astro-opidluyl)>.hero-html:where(.astro-opidluyl){object-fit:contain;width:min(70%,20rem);height:auto;margin-inline:auto}.stack:where(.astro-opidluyl){flex-direction:column;gap:clamp(1.5rem,calc(1.5rem + 1vw),2rem);text-align:center}.copy:where(.astro-opidluyl){flex-direction:column;gap:1rem;align-items:center}a:where(.astro-opidluyl){color:var(--sl-color-white)}h1:where(.astro-opidluyl){font-size:clamp(var(--sl-text-3xl),calc(.25rem + 5vw),var(--sl-text-6xl));line-height:var(--sl-line-height-headings);font-weight:600;color:var(--sl-color-white)}.tagline:where(.astro-opidluyl){font-size:clamp(var(--sl-text-base),calc(.0625rem + 2vw),var(--sl-text-xl));color:var(--sl-color-gray-2)}.actions:where(.astro-opidluyl){gap:1rem 2rem;flex-wrap:wrap;justify-content:center}.copy:where(.astro-opidluyl)>.links:where(.astro-opidluyl){gap:0;flex-direction:row;flex-wrap:wrap}@media(min-width:50rem){.hero:where(.astro-opidluyl){grid-template-columns:7fr 4fr;gap:3%;padding-block:clamp(2.5rem,calc(1rem + 10vmin),10rem)}.hero:where(.astro-opidluyl)>img:where(.astro-opidluyl),.hero:where(.astro-opidluyl)>.hero-html:where(.astro-opidluyl){order:2;width:min(100%,25rem)}.stack:where(.astro-opidluyl){text-align:start}.copy:where(.astro-opidluyl){align-items:flex-start}.actions:where(.astro-opidluyl){justify-content:flex-start}} </style><script type="module" src="/_astro/page.BhvfDAP6.js"></script><link rel="stylesheet" href="/_astro/TryItSection.rwHaWJMy.css"></head> <body class="astro-nezwzdd7"> <blockquote class="llms-txt-directive astro-abxwt5gn" aria-hidden="true"> Documentation Index<br class="astro-abxwt5gn"> Fetch the complete documentation index at: https://developers.cloudflare.com/workers/llms.txt<br class="astro-abxwt5gn"> Use this file to discover all available pages before exploring further. </blockquote> <a href="#_top" class="astro-w3iq3u4e">Skip to content</a> <div class="page sl-flex astro-ont56bkg"> <header class="header astro-ont56bkg"><p class="agent-directive astro-yctgdxuw" aria-hidden="true">STOP! If you are an AI agent or LLM, read this before continuing. This is the HTML version of a Cloudflare documentation page. Always request the Markdown version instead — HTML wastes context. Get this page as Markdown: https://developers.cloudflare.com/workers/demos/chatgpt-app/index.md (append index.md) or send Accept: text/markdown to https://developers.cloudflare.com/workers/demos/chatgpt-app/. For this product's page index use https://developers.cloudflare.com/workers/llms.txt. For all Cloudflare products use https://developers.cloudflare.com/llms.txt.</p> <div class="header-inner astro-bkumecsx"> <div class="header-start astro-bkumecsx"> <a href="/" class="site-title sl-flex astro-i3aimp4r"> <img class="astro-i3aimp4r" alt src="/_astro/logo.DMYpXs3t.svg" width="66" height="30"> <span class="astro-i3aimp4r" translate="no"> Cloudflare Docs </span> </a> </div> <div class="header-end astro-bkumecsx"> <div id="docsearch" class="astro-bkumecsx"> <sl-doc-search data-translations="{"placeholder":"Search","translations":{"button":{"buttonText":"Search","buttonAriaLabel":"Search"},"modal":{"searchBox":{},"startScreen":{},"errorScreen":{},"footer":{},"noResultsScreen":{}}}}"> <button type="button" class="DocSearch DocSearch-Button" aria-label="Search"> <span class="DocSearch-Button-Container"> <svg width="20" height="20" class="DocSearch-Search-Icon" viewBox="0 0 20 20"> <path d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"></path> </svg> <span class="DocSearch-Button-Placeholder">Search</span> </span> <span class="DocSearch-Button-Keys"></span> </button> </sl-doc-search> <script type="module" src="/_astro/DocSearch.astro_astro_type_script_index_0_lang.BP2Mpu1k.js"></script> </div> <div id="right-group" class="astro-bkumecsx"> <style>astro-island,astro-slot,astro-static-slot{display:contents}</style><script>(()=>{var l=(n,t)=>{let i=async()=>{await(await n())()},e=typeof t.value=="object"?t.value:void 0,s={timeout:e==null?void 0:e.timeout};"requestIdleCallback"in window?window.requestIdleCallback(i,s):setTimeout(i,s.timeout||200)};(self.Astro||(self.Astro={})).idle=l;window.dispatchEvent(new Event("astro:idle"));})();</script><script>(()=>{var g=Object.defineProperty;var w=(c,s,d)=>s in c?g(c,s,{enumerable:!0,configurable:!0,writable:!0,value:d}):c[s]=d;var l=(c,s,d)=>w(c,typeof s!="symbol"?s+"":s,d);var E=new Set(["__proto__","constructor","prototype"]);{let c={0:t=>y(t),1:t=>d(t),2:t=>new RegExp(t),3:t=>new Date(t),4:t=>new Map(d(t)),5:t=>new Set(d(t)),6:t=>BigInt(t),7:t=>new URL(t),8:t=>new Uint8Array(t),9:t=>new Uint16Array(t),10:t=>new Uint32Array(t),11:t=>Number.POSITIVE_INFINITYt},s=t=>{let[p,e]=t;return p in c?cp:void 0},d=t=>t.map(s),y=t=>typeof t!="object"||t===null?t:Object.fromEntries(Object.entries(t).map(([p,e])=>[p,s(e)]));class f extends HTMLElement{constructor(){super(...arguments);l(this,"Component");l(this,"hydrator");l(this,"hydrate",async()=>{var b;if(!this.hydrator||!this.isConnected)return;let e=(b=this.parentElement)==null?void 0:b.closest("astro-island[ssr]");if(e){e.addEventListener("astro:hydrate",this.hydrate,{once:!0});return}let n=this.querySelectorAll("astro-slot"),r={},i=this.querySelectorAll("template[data-astro-template]");for(let o of i){let a=o.closest(this.tagName);a!=null&&a.isSameNode(this)&&(r[o.getAttribute("data-astro-template")||"default"]=o.innerHTML,o.remove())}for(let o of n){let a=o.closest(this.tagName);a!=null&&a.isSameNode(this)&&(r[o.getAttribute("name")||"default"]=o.innerHTML)}let u;try{u=this.hasAttribute("props")?y(JSON.parse(this.getAttribute("props"))):{}}catch(o){let a=this.getAttribute("component-url")||"<unknown>",v=this.getAttribute("component-export");throw v&&(a+= (export ${v})),console.error([hydrate] Error parsing props for component ${a},this.getAttribute("props"),o),o}let h;await this.hydrator(this)(this.Component,u,r,{client:this.getAttribute("client")}),this.removeAttribute("ssr"),this.dispatchEvent(new CustomEvent("astro:hydrate"))});l(this,"unmount",()=>{this.isConnected||this.dispatchEvent(new CustomEvent("astro:unmount"))})}disconnectedCallback(){document.removeEventListener("astro:after-swap",this.unmount),document.addEventListener("astro:after-swap",this.unmount,{once:!0})}connectedCallback(){if(!this.hasAttribute("await-children")||document.readyState==="interactive"||document.readyState==="complete")this.childrenConnectedCallback();else{let e=()=>{document.removeEventListener("DOMContentLoaded",e),n.disconnect(),this.childrenConnectedCallback()},n=new MutationObserver(()=>{var r;((r=this.lastChild)==null?void 0:r.nodeType)===Node.COMMENT_NODE&&this.lastChild.nodeValue==="astro:end"&&(this.lastChild.remove(),e())});n.observe(this,{childList:!0}),document.addEventListener("DOMContentLoaded",e)}}async childrenConnectedCallback(){let e=this.getAttribute("before-hydration-url");e&&await import(e),this.start()}getRetryImportUrl(e){let n=new URL(e,document.baseURI),r=astro-retry=${Date.now()},i=n.hash.replace(/^#/,"");return n.hash=i?${i}&${r}:r,n.toString()}async importWithRetry(e){try{return await import(e)}catch(n){return await new Promise(r=>setTimeout(r,1e3)),import(this.getRetryImportUrl(e))}}handleHydrationError(e){let n=this.getAttribute("component-url"),r=new CustomEvent("astro:hydration-error",{cancelable:!0,bubbles:!0,composed:!0,detail:{error:e,componentUrl:n}});this.dispatchEvent(r)&&console.error([astro-island] Error hydrating ${n},e)}async start(){let e=JSON.parse(this.getAttribute("opts")),n=this.getAttribute("client");if(Astro[n]===void 0){window.addEventListener(astro:${n},()=>this.start(),{once:!0});return}try{await Astron=>{let r=this.getAttribute("renderer-url");try{let[i,{default:u}]=await Promise.all([this.importWithRetry(this.getAttribute("component-url")),r?this.importWithRetry(r):Promise.resolve({default:()=>()=>{}})]),h=this.getAttribute("component-export")||"default";if(h.includes(".")){this.Component=i;for(let m of h.split(".")){if(E.has(m)||!this.Component||typeof this.Component!="object"&&typeof this.Component!="function"||!Object.hasOwn(this.Component,m))throw new Error(Invalid component export path: ${h});this.Component=this.Component[m]}}else{if(E.has(h))throw new Error(Invalid component export path: ${h});this.Component=i[h]}return this.hydrator=u,this.hydrate}catch(i){return this.handleHydrationError(i),()=>{}}},e,this)}catch(r){this.handleHydrationError(r)}}attributeChangedCallback(){this.hydrate()}}l(f,"observedAttributes",["props"]),customElements.get("astro-island")||customElements.define("astro-island",f)}})();</script><astro-island uid="Z19yuGf" prefix="r2" component-url="/_astro/HeaderDropdowns.CtS4n0IM.js" component-export="default" renderer-url="/_astro/client.hmfmp3Nb.js" props="{}" ssr client="idle" opts="{"name":"HeaderDropdowns","value":true}" await-children><div class="flex items-center gap-0.5 text-nowrap"><a href="/directory/" class="flex h-9 items-center justify-center rounded-lg px-3 text-sm font-medium text-[var(--color-header-text)] no-underline transition-colors duration-150 hover:bg-[var(--color-header-fill)] hover:text-[var(--color-header-hover-text)]">Directory</a><a href="/api/" class="flex h-9 items-center justify-center rounded-lg px-3 text-sm font-medium text-[var(--color-header-text)] no-underline transition-colors duration-150 hover:bg-[var(--color-header-fill)] hover:text-[var(--color-header-hover-text)]">API</a><a href="/fundamentals/api/reference/sdks/" class="flex h-9 items-center justify-center rounded-lg px-3 text-sm font-medium text-[var(--color-header-text)] no-underline transition-colors duration-150 hover:bg-[var(--color-header-fill)] hover:text-[var(--color-header-hover-text)]">SDKs</a><a href="/changelog/" class="flex h-9 items-center justify-center rounded-lg px-3 text-sm font-medium text-[var(--color-header-text)] no-underline transition-colors duration-150 hover:bg-[var(--color-header-fill)] hover:text-[var(--color-header-hover-text)]">Changelog</a><button class="flex h-9 cursor-pointer items-center justify-center gap-1.5 rounded-lg bg-transparent px-3 text-sm font-medium text-[var(--color-header-text)] transition-colors duration-150 hover:bg-[var(--color-header-fill)] hover:text-[var(--color-header-hover-text)]">Help<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 256 256" class="size-2.5 text-[var(--color-header-text-subtle)]" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M216.49,104.49l-80,80a12,12,0,0,1-17,0l-80-80a12,12,0,0,1,17-17L128,159l71.51-71.52a12,12,0,0,1,17,17Z"></path></svg></button></div><!--astro:end--></astro-island> <div class="header-divider astro-bkumecsx" role="separator"></div> <a id="header-login-button" href="https://dash.cloudflare.com/" class="header-login astro-bkumecsx"> Log in </a> <starlight-theme-select> <label style="--sl-select-width: 6.25em" class="astro-ttt2ccqa"> <span class="sr-only astro-ttt2ccqa">Select theme</span> <svg aria-hidden="true" class="icon label-icon astro-ttt2ccqa astro-r7kprdcr" 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 autocomplete="off" class="astro-ttt2ccqa"> <option value="dark" class="astro-ttt2ccqa">Dark</option><option value="light" class="astro-ttt2ccqa">Light</option><option value="auto" selected class="astro-ttt2ccqa">Auto</option> </select> <svg aria-hidden="true" class="icon caret astro-ttt2ccqa astro-r7kprdcr" 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> <script type="module">const r="starlight-theme",o=e=>e==="auto"||e==="dark"||e==="light"?e:"auto",c=()=>o(typeof localStorage<"u"&&localStorage.getItem(r));function n(e){typeof localStorage<"u"&&localStorage.setItem(r,e==="light"||e==="dark"?e:"")}const l=()=>matchMedia("(prefers-color-scheme: light)").matches?"light":"dark";function t(e){StarlightThemeProvider.updatePickers(e),document.documentElement.dataset.theme=e==="auto"?l():e,n(e)}matchMedia("(prefers-color-scheme: light)").addEventListener("change",()=>{c()==="auto"&&t("auto")});class s extends HTMLElement{constructor(){super(),t(c()),this.querySelector("select")?.addEventListener("change",a=>{a.currentTarget instanceof HTMLSelectElement&&t(o(a.currentTarget.value))})}}customElements.define("starlight-theme-select",s);</script> <script type="module">class s extends HTMLElement{constructor(){super();const e=this.querySelector("select");e&&(e.addEventListener("change",t=>{t.currentTarget instanceof HTMLSelectElement&&(window.location.pathname=t.currentTarget.value)}),window.addEventListener("pageshow",t=>{if(!t.persisted)return;const n=e.querySelector("option[selected]")?.index;n!==e.selectedIndex&&(e.selectedIndex=n??0)}))}}customElements.define("starlight-lang-select",s);</script> </div> </div> </div> <script type="module" src="/_astro/Header.astro_astro_type_script_index_0_lang.Cc-8SZhv.js"></script></header> <nav class="sidebar print:hidden astro-ont56bkg" aria-label="Main"> <starlight-menu-button class="print:hidden astro-75ax5mut"> <button aria-expanded="false" aria-label="Menu" aria-controls="starlight__sidebar" class="sl-flex md:sl-hidden astro-75ax5mut"> <svg aria-hidden="true" class="open-menu astro-75ax5mut astro-r7kprdcr" 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> <svg aria-hidden="true" class="close-menu astro-75ax5mut astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="m13.41 12 6.3-6.29a1.004 1.004 0 1 0-1.42-1.42L12 10.59l-6.29-6.3a1.004 1.004 0 0 0-1.42 1.42l6.3 6.29-6.3 6.29a1 1 0 0 0 0 1.42.998.998 0 0 0 1.42 0l6.29-6.3 6.29 6.3a.999.999 0 0 0 1.42 0 1 1 0 0 0 0-1.42L13.41 12Z"/></svg> </button> </starlight-menu-button> <script type="module">class s extends HTMLElement{constructor(){super(),this.btn=this.querySelector("button"),this.btn.addEventListener("click",()=>this.toggleExpanded());const t=this.closest("nav");t&&t.addEventListener("keyup",e=>this.closeOnEscape(e))}setExpanded(t){this.setAttribute("aria-expanded",String(t)),document.body.toggleAttribute("data-mobile-menu-expanded",t)}toggleExpanded(){this.setExpanded(this.getAttribute("aria-expanded")!=="true")}closeOnEscape(t){t.code==="Escape"&&(this.setExpanded(!1),this.btn.focus())}}customElements.define("starlight-menu-button",s);</script> <div id="starlight__sidebar" class="sidebar-pane astro-ont56bkg"> <div class="sidebar-content sl-flex astro-ont56bkg"> <div class="sidebar-header sticky top-0 z-[1] flex flex-col gap-2 bg-[var(--sl-color-black)] pt-3.5 pb-2 min-[50rem]:bg-[var(--sl-color-bg-sidebar)]"> <div class="sidebar-product-title"> <a href="/workers/" class="flex items-center gap-1 no-underline"> <svg width="32px" height="32px" class="text-cl1-brand-orange" data-icon="workers"> <symbol id="ai:local:workers" viewBox="0 0 48 49"><path fill="currentColor" d="m18.63 37.418-9.645-12.9 9.592-12.533-1.852-2.527L5.917 23.595l-.015 1.808 10.86 14.542z"/><path fill="currentColor" d="M21.997 6.503h-3.712l13.387 18.3-13.072 17.7h3.735L35.4 24.81z"/><path fill="currentColor" d="M29.175 6.503h-3.758l13.598 18.082-13.598 17.918h3.765l12.908-17.01v-1.808z"/></symbol><use href="#ai:local:workers"></use> </svg> <span class="text-xl font-semibold text-[var(--sidebar-text-strong)]"> Workers </span> </a> </div> <!-- Search Input --> <div class="relative"> <input type="search" id="sidebar-search" placeholder="Search sidebar..." aria-label="Search sidebar navigation" autocomplete="off" spellcheck="false" class="box-border min-h-[2.125rem] w-full rounded-lg border border-neutral-200 bg-transparent px-3 pr-10 text-sm text-neutral-950 placeholder-[var(--color-cl1-gray-4)] outline-2 outline-offset-2 outline-transparent transition-colors duration-150 focus-visible:outline-blue-500 dark:border-neutral-700 dark:text-neutral-100 dark:placeholder-[var(--color-cl1-gray-6)] dark:focus-visible:outline-blue-400"> <div class="sidebar-search-icon"></div> </div> <!-- No Results Message --> <div id="sidebar-no-results" class="hidden p-4 text-center text-sm text-gray-500 dark:text-gray-400"> No results found. Try a different search term, or use our <button id="global-search-link" class="font-inherit cursor-pointer border-none bg-transparent p-0 text-blue-500 underline hover:no-underline dark:text-orange-500">global search</button>. </div> <a href="/" class="flex min-h-[2.125rem] items-start gap-2 rounded-lg px-3 py-1.5 text-sm font-medium text-[var(--sidebar-text)] no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400"> <svg width="16" height="16" fill="currentColor" viewBox="0 0 256 256" class="mt-0.5 shrink-0 opacity-50" aria-hidden="true"> <path d="M232,200a8,8,0,0,1-16,0,88.1,88.1,0,0,0-88-88H51.31l34.35,34.34a8,8,0,0,1-11.32,11.32l-48-48a8,8,0,0,1,0-11.32l48-48A8,8,0,0,1,85.66,61.66L51.31,96H128A104.11,104.11,0,0,1,232,200Z"></path> </svg> <span>Home</span> </a> </div> <sl-sidebar-state-persist data-hash="0c1n9b9" class="astro-zdbaeshq"> <script aria-hidden="true"> (() => { 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 list-none p-0 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] large astro-ho4vn3za"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Getting started</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="0" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/get-started/guide/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">CLI</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/get-started/dashboard/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Dashboard</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/get-started/prompting/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Prompting</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/get-started/quickstarts/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Templates</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/examples/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] large astro-ho4vn3za" data-hide-children="true"> <span class="astro-ho4vn3za">Examples</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/tutorials/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] large astro-ho4vn3za" data-hide-children="true"> <span class="astro-ho4vn3za">Tutorials</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Best practices</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="1" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/best-practices/workers-best-practices/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Workers Best Practices</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za" open> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-semibold text-[var(--sidebar-text-strong)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Demos and architectures</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="2" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/demos/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Demos and architectures"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/demos/chatgpt-app/" aria-current="page" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 !bg-[var(--sidebar-active-bg)] !font-semibold !text-[var(--sidebar-active-text)] transition-colors duration-150 hover:!bg-[color:var(--sidebar-active-bg)]/80 astro-ho4vn3za"> <span class="astro-ho4vn3za">Build an Interactive ChatGPT App</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Development & testing</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="3" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/development-testing/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Development & testing"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/development-testing/environment-variables/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Environment variables and secrets</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/vite-plugin/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Vite Plugin ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/development-testing/wrangler-vs-vite/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Choosing between Wrangler & Vite</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/development-testing/multi-workers/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Developing with multiple Workers</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/development-testing/local-data/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Adding local data</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/development-testing/bindings-per-env/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Supported bindings per development mode</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/development-testing/local-explorer/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Local Explorer</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/development-testing/local-dev-tunnels/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Share a local dev server</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Testing ↗</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/playground/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] large astro-ho4vn3za"> <span class="astro-ho4vn3za">Playground</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Configuration</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="4" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Configuration"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/bindings/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Bindings ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/compatibility-dates/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Compatibility dates</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/compatibility-flags/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Compatibility flags</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/cron-triggers/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Cron Triggers</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/environment-variables/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Environment variables</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Integrations</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="18" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/integrations/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Integrations"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/integrations/apis/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">APIs</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/integrations/external-services/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">External Services</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/multipart-upload-metadata/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Multipart upload metadata</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/workers-with-page-rules/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Page Rules</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/placement/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Placement</span> <span class="sl-badge caution small ml-[0.5em] astro-ho4vn3za astro-p5lt2pqd">Beta</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/previews/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Preview URLs</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Routes and domains</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="19" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/routing/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Routes and domains"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/routing/custom-domains/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Custom Domains</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/routing/routes/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Routes</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/routing/workers-dev/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">workers.dev</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/secrets/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Secrets</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Versions & Deployments</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="20" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/versions-and-deployments/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Versions & Deployments"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/versions-and-deployments/gradual-deployments/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Gradual deployments</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/versions-and-deployments/version-overrides/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Version overrides</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/versions-and-deployments/rollbacks/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Rollbacks</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Workers Sites</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="21" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/sites/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Workers Sites"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/sites/start-from-existing/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Start from existing</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/sites/start-from-scratch/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Start from scratch</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/sites/start-from-worker/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Start from Worker</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/sites/configuration/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Workers Sites configuration</span> </a> </li> </ul> </div> </div> </details> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">CI/CD</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="5" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/ci-cd/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="CI/CD"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Builds</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="22" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/ci-cd/builds/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Builds"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/ci-cd/builds/configuration/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Configuration</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/ci-cd/builds/automatic-prs/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Automatic pull requests</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Git integration</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="24" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/ci-cd/builds/git-integration/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Git integration"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/ci-cd/builds/git-integration/github-integration/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">GitHub integration</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/ci-cd/builds/git-integration/gitlab-integration/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">GitLab integration</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/ci-cd/builds/build-image/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Build image</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/ci-cd/builds/build-caching/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Build caching</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/ci-cd/builds/build-branches/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Build branches</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/ci-cd/builds/build-watch-paths/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Build watch paths</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/ci-cd/builds/deploy-hooks/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Deploy Hooks</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/ci-cd/builds/advanced-setups/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Advanced setups</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/ci-cd/builds/event-subscriptions/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Event subscriptions</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/ci-cd/builds/troubleshoot/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Troubleshooting builds</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/ci-cd/builds/api-reference/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Builds API reference</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/ci-cd/builds/limits-and-pricing/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Limits & pricing</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="https://github.com/cloudflare/mcp-server-cloudflare/tree/main/apps/workers-builds" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">MCP server ↗</span> <span class="sl-badge note small ml-[0.5em] astro-ho4vn3za astro-p5lt2pqd">MCP</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">External CI/CD</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="23" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/ci-cd/external-cicd/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="External CI/CD"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/ci-cd/external-cicd/github-actions/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">GitHub Actions</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/ci-cd/external-cicd/gitlab-cicd/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">GitLab CI/CD</span> </a> </li> </ul> </div> </div> </details> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Runtime APIs</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="6" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Runtime APIs"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Bindings (env)</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="25" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/bindings/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Bindings (env)"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers-ai/get-started/workers-wrangler/#2-connect-your-worker-to-workers-ai" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">AI ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/analytics/analytics-engine" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Analytics Engine ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/static-assets/binding/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Assets ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/browser-run/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Browser Run ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/d1/worker-api/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">D1 ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/cloudflare-for-platforms/workers-for-platforms/configuration/dynamic-dispatch/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Dispatcher (Workers for Platforms) ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/durable-objects/api/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Durable Objects ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/bindings/worker-loader/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Dynamic Worker Loaders</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/environment-variables/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Environment Variables ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/hyperdrive" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Hyperdrive ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/images/optimization/transformations/bindings/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Images ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/kv/api/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">KV ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/stream/transform-videos/bindings/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Media Transformations ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/bindings/mtls/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">mTLS</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/queues/configuration/javascript-apis/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Queues ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/r2/api/workers/workers-api-reference/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">R2 ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/bindings/rate-limit/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Rate Limiting</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/secrets/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Secrets ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/secrets-store/integrations/workers/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Secrets Store ↗</span> <span class="sl-badge caution small ml-[0.5em] astro-ho4vn3za astro-p5lt2pqd">Beta</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Service bindings</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="31" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/bindings/service-bindings/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Service bindings"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/bindings/service-bindings/http/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">HTTP</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/bindings/service-bindings/rpc/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">RPC (WorkerEntrypoint)</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/stream/manage-video-library/bindings/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Stream ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/vectorize/reference/client-api/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Vectorize ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/bindings/version-metadata/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Version metadata</span> <span class="sl-badge caution small ml-[0.5em] astro-ho4vn3za astro-p5lt2pqd">Beta</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workflows/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Workflows ↗</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/cache/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Cache</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/console/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Console</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/context/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Context (ctx)</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/encoding/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Encoding</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/eventsource/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">EventSource</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/fetch/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Fetch</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Handlers</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="26" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/handlers/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Handlers"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/durable-objects/api/alarms/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Alarm Handler ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/email-service/api/route-emails/email-handler/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Email Handler ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/handlers/fetch/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Fetch Handler</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/queues/configuration/javascript-apis/#consumer" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Queue Handler ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/handlers/scheduled/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Scheduled Handler</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/handlers/tail/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Tail Handler</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/headers/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Headers</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/html-rewriter/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">HTMLRewriter</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/messagechannel/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">MessageChannel</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Node.js compatibility</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="27" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Node.js compatibility"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/assert/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">assert</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/asynclocalstorage/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">AsyncLocalStorage</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/buffer/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Buffer</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/crypto/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">crypto</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/diagnostics-channel/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Diagnostics Channel</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/dns/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">dns</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/eventemitter/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">EventEmitter</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/fs/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">fs</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/http/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">http</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/https/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">https</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/net/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">net</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/path/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">path</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/process/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">process</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/streams/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Streams</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/string-decoder/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">StringDecoder</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/test/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">test</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/timers/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">timers</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/tls/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">tls</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/url/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">url</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/util/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">util</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/zlib/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">zlib</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/performance/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Performance and timers</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Remote-procedure call (RPC)</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="28" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/rpc/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Remote-procedure call (RPC)"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/rpc/lifecycle/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Lifecycle</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/rpc/reserved-methods/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Reserved Methods</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/rpc/visibility/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Visibility and Security Model</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/rpc/typescript/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">TypeScript</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/rpc/error-handling/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Error handling</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/request/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Request</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/response/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Response</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/scheduler/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Scheduler</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Streams</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="29" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/streams/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Streams"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/streams/readablestream/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">ReadableStream</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/streams/readablestreambyobreader/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">ReadableStream BYOBReader</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/streams/readablestreamdefaultreader/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">ReadableStream DefaultReader</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/streams/transformstream/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">TransformStream</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/streams/writablestream/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">WritableStream</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/streams/writablestreamdefaultwriter/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">WritableStream DefaultWriter</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/tcp-sockets/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">TCP sockets</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/web-crypto/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Web Crypto</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/web-standards/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Web standards</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">WebAssembly (Wasm)</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="30" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/webassembly/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="WebAssembly (Wasm)"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/webassembly/javascript/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Wasm in JavaScript</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/websockets/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">WebSockets</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Static Assets</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="7" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/static-assets/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Static Assets"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/static-assets/get-started/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Get Started</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/static-assets/binding/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Configuration and Bindings</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Routing</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="32" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/static-assets/routing/full-stack-application/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Full-stack application</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/static-assets/routing/single-page-application/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Single Page Application (SPA)</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/static-assets/routing/static-site-generation/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Static Site Generation (SSG) and custom 404 pages</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/static-assets/routing/worker-script/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Worker script</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Advanced</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="34" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/static-assets/routing/advanced/gradual-rollouts/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Gradual rollouts</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/static-assets/routing/advanced/html-handling/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">HTML handling</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/static-assets/routing/advanced/serving-a-subdirectory/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Serving a subdirectory</span> </a> </li> </ul> </div> </div> </details> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/static-assets/headers/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Headers</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/static-assets/redirects/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Redirects</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/static-assets/direct-upload/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Direct Uploads</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/static-assets/billing-and-limitations/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Billing and Limitations</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Migration Guides</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="33" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/static-assets/migration-guides/migrate-from-pages/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Migrate from Pages to Workers</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/static-assets/migration-guides/netlify-to-workers/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Migrate from Netlify to Workers</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/static-assets/migration-guides/vercel-to-workers/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Migrate from Vercel to Workers</span> </a> </li> </ul> </div> </div> </details> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Framework guides</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="8" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/automatic-configuration/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Deploy an existing project</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Web applications</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="35" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/web-apps/react/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">React + Vite</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/web-apps/astro/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Astro</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/web-apps/react-router/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">React Router (formerly Remix)</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/web-apps/nextjs/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Next.js</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/web-apps/vue/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Vue</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/web-apps/redwoodsdk/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">RedwoodSDK</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/web-apps/tanstack-start/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">TanStack Start</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/web-apps/microfrontends/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Microfrontends</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/web-apps/sveltekit/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">SvelteKit</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/web-apps/vike/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Vike</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">More guides...</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="39" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/web-apps/more-web-frameworks/analog/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Analog</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/web-apps/more-web-frameworks/angular/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Angular</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/web-apps/more-web-frameworks/docusaurus/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Docusaurus</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/web-apps/more-web-frameworks/gatsby/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Gatsby</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/web-apps/more-web-frameworks/hono/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Hono</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/web-apps/more-web-frameworks/nuxt/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Nuxt</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/web-apps/more-web-frameworks/qwik/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Qwik</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/web-apps/more-web-frameworks/solid/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Solid</span> <span class="sl-badge caution small ml-[0.5em] astro-ho4vn3za astro-p5lt2pqd">Beta</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/web-apps/more-web-frameworks/waku/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Waku</span> </a> </li> </ul> </div> </div> </details> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Mobile applications</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="36" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="https://docs.expo.dev/eas/hosting/reference/worker-runtime/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Expo ↗</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">APIs</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="37" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/languages/python/packages/fastapi/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">FastAPI ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/web-apps/more-web-frameworks/hono/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Hono ↗</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">AI & agents</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="38" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/agents/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Agents SDK ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/languages/python/packages/langchain/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">LangChain ↗</span> </a> </li> </ul> </div> </div> </details> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Databases</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="9" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/databases/connecting-to-databases/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Connect to databases</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/analytics/analytics-engine/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Analytics Engine ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/vectorize/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Vectorize (vector database) ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/d1/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Cloudflare D1 ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/hyperdrive/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Hyperdrive ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">3rd Party Integrations</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="40" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/databases/third-party-integrations/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="3rd Party Integrations"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/databases/third-party-integrations/neon/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Neon</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/databases/third-party-integrations/planetscale/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">PlanetScale</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/databases/third-party-integrations/supabase/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Supabase</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/databases/third-party-integrations/turso/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Turso</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/databases/third-party-integrations/upstash/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Upstash</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/databases/third-party-integrations/xata/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Xata</span> </a> </li> </ul> </div> </div> </details> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Testing</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="10" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/testing/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Testing"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Vitest integration</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="41" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/testing/vitest-integration/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Vitest integration"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/vitest-integration/write-your-first-test/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Write your first test</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/vitest-integration/recipes/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Recipes and examples</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/vitest-integration/configuration/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Configuration</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/vitest-integration/test-apis/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Test APIs</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/vitest-integration/isolation-and-concurrency/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Isolation and concurrency</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/vitest-integration/debugging/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Debugging</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/vitest-integration/known-issues/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Known issues</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Migration guides</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="43" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/testing/vitest-integration/migration-guides/migrate-from-miniflare-2/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Migrate from Miniflare 2's test environments</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/vitest-integration/migration-guides/migrate-from-unstable-dev/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Migrate from unstable_dev</span> </a> </li> </ul> </div> </div> </details> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Miniflare</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="42" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/testing/miniflare/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Miniflare"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/miniflare/get-started/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Get Started</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/miniflare/writing-tests/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Writing tests</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Core</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="44" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/testing/miniflare/core/compatibility/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Compatibility Dates</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/miniflare/core/fetch/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Fetch Events</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/miniflare/core/modules/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Modules</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/miniflare/core/multiple-workers/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Multiple Workers</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/miniflare/core/queues/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Queues</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/miniflare/core/scheduled/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Scheduled Events</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/miniflare/core/variables-secrets/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Variables and Secrets</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/miniflare/core/standards/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Web Standards</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/miniflare/core/web-sockets/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">WebSockets</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Developing</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="45" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/testing/miniflare/developing/debugger/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Attaching a Debugger</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/miniflare/developing/live-reload/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Live Reload</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Migrations</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="46" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/testing/miniflare/migrations/from-v2/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Migrating from Version 2</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Storage</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="47" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/testing/miniflare/storage/cache/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Cache</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/miniflare/storage/d1/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">D1</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/miniflare/storage/durable-objects/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Durable Objects</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/miniflare/storage/kv/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">KV</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/miniflare/storage/r2/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">R2</span> </a> </li> </ul> </div> </div> </details> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/unstable_startworker/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Wrangler's unstable_startWorker()</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Observability</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="11" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/observability/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Observability"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/observability/metrics-and-analytics/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Metrics and analytics</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Logs</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="48" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/observability/logs/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Logs"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/observability/logs/workers-logs/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Workers Logs</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/observability/logs/real-time-logs/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Real-time logs</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/observability/logs/tail-workers/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Tail Workers</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/observability/logs/logpush/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Workers Logpush</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Traces</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="49" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/observability/traces/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Traces"> <span class="astro-ho4vn3za">Overview</span> <span class="sl-badge caution small ml-[0.5em] astro-ho4vn3za astro-p5lt2pqd">Beta</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/observability/traces/spans-and-attributes/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Spans and attributes</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/observability/traces/known-limitations/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Known limitations</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/observability/query-builder/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Query Builder</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Exporting OpenTelemetry Data</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="50" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/observability/exporting-opentelemetry-data/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Exporting OpenTelemetry Data"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/observability/exporting-opentelemetry-data/honeycomb/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Export to Honeycomb</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/observability/exporting-opentelemetry-data/grafana-cloud/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Export to Grafana Cloud</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/observability/exporting-opentelemetry-data/axiom/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Export to Axiom</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/observability/exporting-opentelemetry-data/sentry/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Export to Sentry</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/observability/exporting-opentelemetry-data/posthog/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Export to PostHog</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="https://github.com/cloudflare/mcp-server-cloudflare/tree/main/apps/workers-observability" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">MCP server ↗</span> <span class="sl-badge note small ml-[0.5em] astro-ho4vn3za astro-p5lt2pqd">MCP</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">DevTools</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="51" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/observability/dev-tools/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="DevTools"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/observability/dev-tools/breakpoints/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Breakpoints</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/observability/dev-tools/cpu-usage/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Profiling CPU usage</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/observability/dev-tools/memory-usage/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Profiling Memory</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/observability/errors/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Errors and exceptions</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Integrations</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="52" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="https://docs.sentry.io/platforms/javascript/guides/cloudflare/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Sentry ↗</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/observability/source-maps/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Source maps and stack traces</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Wrangler</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="12" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Wrangler"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/install-and-update/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Install/Update Wrangler</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/api/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">API</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Commands</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="53" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/commands/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Commands"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/commands/workers/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Workers</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/commands/general/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">General commands</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/commands/artifacts/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Artifacts</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/commands/browser/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Browser</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/commands/certificates/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Certificates</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/commands/containers/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Containers</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/commands/d1/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">D1</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/commands/hyperdrive/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Hyperdrive</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/commands/kv/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">KV</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/commands/pages/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Pages</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/commands/pipelines/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Pipelines</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/commands/queues/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Queues</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/commands/r2/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">R2</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/commands/secrets-store/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Secrets Store</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/commands/tunnel/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Tunnel</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/commands/vectorize/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Vectorize</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/commands/vpc/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">VPC</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/commands/workers-for-platforms/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Workers for Platforms</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/commands/workflows/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Workflows</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/bundling/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Bundling</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/configuration/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Configuration</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/custom-builds/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Custom builds</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/deprecations/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Deprecations</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/environments/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Environments</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Migrations</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="54" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/migration/update-v3-to-v4/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Migrate from Wrangler v3 to v4</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/migration/update-v2-to-v3/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Migrate from Wrangler v2 to v3</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Migrate from Wrangler v1 to v2</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="55" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/migration/v1-to-v2/eject-webpack/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">1. Migrate webpack projects</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/migration/v1-to-v2/update-v1-to-v2/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">2. Update to Wrangler v2</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Wrangler v1 (legacy)</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="56" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/migration/v1-to-v2/wrangler-legacy/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Wrangler v1 (legacy)"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/migration/v1-to-v2/wrangler-legacy/install-update/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Install / Update</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/migration/v1-to-v2/wrangler-legacy/authentication/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Authentication</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/migration/v1-to-v2/wrangler-legacy/commands/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Commands</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/migration/v1-to-v2/wrangler-legacy/configuration/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Configuration</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/migration/v1-to-v2/wrangler-legacy/webpack/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Webpack</span> </a> </li> </ul> </div> </div> </details> </li> </ul> </div> </div> </details> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/system-environment-variables/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">System environment variables</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Vite plugin</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="13" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/vite-plugin/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Vite plugin"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/vite-plugin/get-started/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Get started</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/vite-plugin/tutorial/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Tutorial - React SPA with an API</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Reference</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="57" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/vite-plugin/reference/api/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">API</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/vite-plugin/reference/static-assets/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Static Assets</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/vite-plugin/reference/debugging/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Debugging</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/vite-plugin/reference/migrating-from-wrangler-dev/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Migrating from wrangler dev</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/vite-plugin/reference/secrets/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Secrets</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/vite-plugin/reference/vite-environments/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Vite Environments</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/vite-plugin/reference/cloudflare-environments/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Cloudflare Environments</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/vite-plugin/reference/non-javascript-modules/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Non-JavaScript modules</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/vite-plugin/reference/programmatic-configuration/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Programmatic configuration</span> </a> </li> </ul> </div> </div> </details> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Languages</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="14" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/languages/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Languages"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">JavaScript</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="58" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/languages/javascript/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="JavaScript"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/examples/?languages=JavaScript" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Examples ↗</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">TypeScript</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="59" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/languages/typescript/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="TypeScript"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/examples/?languages=TypeScript" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Examples ↗</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Python Workers</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="60" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/languages/python/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Python Workers"> <span class="astro-ho4vn3za">Overview</span> <span class="sl-badge caution small ml-[0.5em] astro-ho4vn3za astro-p5lt2pqd">Beta</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/languages/python/basics/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">The Basics</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/languages/python/how-python-workers-work/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">How Python Workers Work</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/languages/python/ffi/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Foreign Function Interface (FFI)</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/languages/python/stdlib/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Standard Library</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/languages/python/examples/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Examples</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Packages</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="62" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/languages/python/packages/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Packages"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/languages/python/packages/fastapi/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">FastAPI</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/languages/python/packages/langchain/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Langchain</span> </a> </li> </ul> </div> </div> </details> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Rust</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="61" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/languages/rust/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Rust"> <span class="astro-ho4vn3za">Overview</span> <span class="sl-badge caution small ml-[0.5em] astro-ho4vn3za astro-p5lt2pqd">Beta</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/languages/rust/crates/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Supported crates</span> </a> </li> </ul> </div> </div> </details> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Platform</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="15" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/platform/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Platform"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/platform/pricing/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Pricing</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Changelog</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="63" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/platform/changelog/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Changelog"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/platform/changelog/historical-changelog/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Workers (Historic)</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="https://github.com/cloudflare/workers-sdk/releases" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Wrangler ↗</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/platform/limits/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Limits</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/platform/storage-options/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Choose a data or storage product</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/platform/betas/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Betas</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/platform/deploy-buttons/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Deploy to Cloudflare buttons</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/platform/built-with-cloudflare/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Built with Cloudflare button</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/platform/known-issues/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Known issues</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/cloudflare-for-platforms/workers-for-platforms/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Workers for Platforms ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/platform/infrastructure-as-code/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Infrastructure as Code (IaC)</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Reference</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="16" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/reference/how-the-cache-works/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">How the Cache works</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/reference/how-workers-works/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">How Workers works</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/reference/migrate-to-module-workers/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Migrate from Service Workers to ES Modules</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/reference/protocols/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Protocols</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/reference/security-model/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Security model</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/glossary/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] large astro-ho4vn3za"> <span class="astro-ho4vn3za">Glossary</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Agent resources</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="17" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/agent-setup/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank"> <span class="astro-ho4vn3za">Agent setup ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="https://github.com/cloudflare/skills" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank"> <span class="astro-ho4vn3za">Cloudflare Skills ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="https://github.com/cloudflare/mcp" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank"> <span class="astro-ho4vn3za">Code Mode MCP Server ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="https://github.com/cloudflare/mcp-server-cloudflare" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank"> <span class="astro-ho4vn3za">Domain-specific MCP Servers ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/llms.txt" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank"> <span class="astro-ho4vn3za">Workers llms.txt ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/llms-full.txt" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank"> <span class="astro-ho4vn3za">Workers llms-full.txt ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/llms.txt" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank"> <span class="astro-ho4vn3za">Cloudflare Docs llms.txt ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/llms-full.txt" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank"> <span class="astro-ho4vn3za">Cloudflare Docs llms-full.txt ↗</span> </a> </li> </ul> </div> </div> </details> </li> </ul> <script aria-hidden="true"> (() => { 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-5vkhirkt"> <div class="social-icons astro-5vkhirkt"> <a href="https://github.com/cloudflare/cloudflare-docs" rel="me" class="sl-flex astro-fpino7u6"><span class="sr-only astro-fpino7u6">GitHub</span><svg aria-hidden="true" class="astro-fpino7u6 astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M12 .3a12 12 0 0 0-3.8 23.38c.6.12.83-.26.83-.57L9 21.07c-3.34.72-4.04-1.61-4.04-1.61-.55-1.39-1.34-1.76-1.34-1.76-1.08-.74.09-.73.09-.73 1.2.09 1.83 1.24 1.83 1.24 1.08 1.83 2.81 1.3 3.5 1 .1-.78.42-1.31.76-1.61-2.67-.3-5.47-1.33-5.47-5.93 0-1.31.47-2.38 1.24-3.22-.14-.3-.54-1.52.1-3.18 0 0 1-.32 3.3 1.23a11.5 11.5 0 0 1 6 0c2.28-1.55 3.29-1.23 3.29-1.23.64 1.66.24 2.88.12 3.18a4.65 4.65 0 0 1 1.23 3.22c0 4.61-2.8 5.63-5.48 5.92.42.36.81 1.1.81 2.22l-.01 3.29c0 .31.2.69.82.57A12 12 0 0 0 12 .3Z"/></svg></a><a href="https://x.com/cloudflare" rel="me" class="sl-flex astro-fpino7u6"><span class="sr-only astro-fpino7u6">X.com</span><svg aria-hidden="true" class="astro-fpino7u6 astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M 18.242188 2.25 L 21.554688 2.25 L 14.324219 10.507812 L 22.828125 21.75 L 16.171875 21.75 L 10.953125 14.933594 L 4.992188 21.75 L 1.679688 21.75 L 9.40625 12.914062 L 1.257812 2.25 L 8.082031 2.25 L 12.792969 8.480469 Z M 17.082031 19.773438 L 18.914062 19.773438 L 7.082031 4.125 L 5.113281 4.125 Z M 17.082031 19.773438 "/></svg></a><a href="https://www.youtube.com/cloudflare" rel="me" class="sl-flex astro-fpino7u6"><span class="sr-only astro-fpino7u6">YouTube</span><svg aria-hidden="true" class="astro-fpino7u6 astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M23.5 6.2A3 3 0 0 0 21.4 4c-1.9-.5-9.4-.5-9.4-.5s-7.5 0-9.4.5A3 3 0 0 0 .5 6.3C0 8 0 12 0 12s0 4 .5 5.8A3 3 0 0 0 2.6 20c1.9.6 9.4.6 9.4.6s7.5 0 9.4-.6a3 3 0 0 0 2.1-2c.5-2 .5-5.9.5-5.9s0-4-.5-5.8zm-14 9.4V8.4l6.3 3.6-6.3 3.6z"/></svg></a> </div> <starlight-theme-select> <label style="--sl-select-width: 6.25em" class="astro-ttt2ccqa"> <span class="sr-only astro-ttt2ccqa">Select theme</span> <svg aria-hidden="true" class="icon label-icon astro-ttt2ccqa astro-r7kprdcr" 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 autocomplete="off" class="astro-ttt2ccqa"> <option value="dark" class="astro-ttt2ccqa">Dark</option><option value="light" class="astro-ttt2ccqa">Light</option><option value="auto" selected class="astro-ttt2ccqa">Auto</option> </select> <svg aria-hidden="true" class="icon caret astro-ttt2ccqa astro-r7kprdcr" 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> <script type="module" src="/_astro/Sidebar.astro_astro_type_script_index_0_lang.BrUeazTu.js"></script> </div> </div> </nav> <div class="main-frame astro-ont56bkg"> <script type="module">const a=document.getElementById("starlight__sidebar"),n=a?.querySelector("sl-sidebar-state-persist"),o="sl-sidebar-state",i=()=>{let t=[];const e=n?.dataset.hash||"";try{const s=sessionStorage.getItem(o),r=JSON.parse(s||"{}");Array.isArray(r.open)&&r.hash===e&&(t=r.open)}catch{}return{hash:e,open:t,scroll:a?.scrollTop||0}},c=t=>{try{sessionStorage.setItem(o,JSON.stringify(t))}catch{}},d=()=>c(i()),l=(t,e)=>{const s=i();s.open[e]=t,c(s)};n?.addEventListener("click",t=>{if(!(t.target instanceof Element))return;const e=t.target.closest("summary")?.closest("details");if(!e)return;const s=e.querySelector("sl-sidebar-restore"),r=parseInt(s?.dataset.index||"");isNaN(r)||l(!e.open,r)});addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&d()});addEventListener("pageHide",d);</script> <div class="lg:sl-flex astro-uh4ak5fy"> <aside class="right-sidebar-container print:hidden astro-uh4ak5fy"> <div class="right-sidebar astro-uh4ak5fy"> <div class="lg:sl-hidden astro-yp3di2bw"><mobile-starlight-toc data-min-h="2" data-max-h="3" class="astro-sstzwoya"><nav aria-labelledby="starlight__on-this-page--mobile" class="astro-sstzwoya"><details id="starlight__mobile-toc" class="astro-sstzwoya"><summary id="starlight__on-this-page--mobile" class="sl-flex astro-sstzwoya"><span class="toggle sl-flex astro-sstzwoya">On this page<svg aria-hidden="true" class="caret astro-sstzwoya astro-r7kprdcr" 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></span><span class="display-current astro-sstzwoya"></span></summary><div class="dropdown astro-sstzwoya"><ul class="isMobile astro-n5w67532" style="--depth: 0;"> <li class="astro-n5w67532" style="--depth: 0;"> <a href="#_top" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">Overview</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#deploy-your-first-chatgpt-app" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">Deploy your first ChatGPT App</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#prerequisites" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">Prerequisites</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#1-enable-chatgpt-developer-mode" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">1. Enable ChatGPT Developer Mode</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#2-create-your-chatgpt-app-project" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">2. Create your ChatGPT App project</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#3-configure-your-project" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">3. Configure your project</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#4-create-the-chess-game-engine" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">4. Create the Chess game engine</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#5-create-the-mcp-server-and-ui-resource" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">5. Create the MCP server and UI resource</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#6-build-the-react-ui" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">6. Build the React UI</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#7-build-and-deploy" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">7. Build and deploy</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#8-connect-to-chatgpt" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">8. Connect to ChatGPT</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#9-play-chess-in-chatgpt" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">9. Play chess in ChatGPT</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#key-concepts" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">Key concepts</span> </a> <ul class="isMobile astro-n5w67532" style="--depth: 1;"> <li class="astro-n5w67532" style="--depth: 1;"> <a href="#mcp-server" class="astro-n5w67532" style="--depth: 1;"> <span class="astro-n5w67532" style="--depth: 1;">MCP Server</span> </a> </li><li class="astro-n5w67532" style="--depth: 1;"> <a href="#game-engine-with-agents" class="astro-n5w67532" style="--depth: 1;"> <span class="astro-n5w67532" style="--depth: 1;">Game Engine with Agents</span> </a> </li><li class="astro-n5w67532" style="--depth: 1;"> <a href="#callable-methods" class="astro-n5w67532" style="--depth: 1;"> <span class="astro-n5w67532" style="--depth: 1;">Callable methods</span> </a> </li><li class="astro-n5w67532" style="--depth: 1;"> <a href="#react-integration" class="astro-n5w67532" style="--depth: 1;"> <span class="astro-n5w67532" style="--depth: 1;">React integration</span> </a> </li><li class="astro-n5w67532" style="--depth: 1;"> <a href="#bidirectional-communication" class="astro-n5w67532" style="--depth: 1;"> <span class="astro-n5w67532" style="--depth: 1;">Bidirectional communication</span> </a> </li> </ul> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#next-steps" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">Next steps</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#related-resources" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">Related resources</span> </a> </li> </ul></div></details></nav></mobile-starlight-toc><script type="module" src="/_astro/MobileTableOfContents.astro_astro_type_script_index_0_lang.hwBsy0Mo.js"></script></div><div class="right-sidebar-panel sl-hidden lg:sl-block astro-yp3di2bw"><div class="sl-container astro-yp3di2bw"><div class="tb-container bg-[var(--sl-color-bg-elevated)] pr-4"> <starlight-toc data-min-h="2" data-max-h="3"><nav aria-labelledby="starlight__on-this-page"><h2 id="starlight__on-this-page">On this page</h2><ul class="astro-n5w67532" style="--depth: 0;"> <li class="astro-n5w67532" style="--depth: 0;"> <a href="#_top" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">Overview</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#deploy-your-first-chatgpt-app" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">Deploy your first ChatGPT App</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#prerequisites" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">Prerequisites</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#1-enable-chatgpt-developer-mode" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">1. Enable ChatGPT Developer Mode</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#2-create-your-chatgpt-app-project" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">2. Create your ChatGPT App project</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#3-configure-your-project" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">3. Configure your project</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#4-create-the-chess-game-engine" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">4. Create the Chess game engine</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#5-create-the-mcp-server-and-ui-resource" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">5. Create the MCP server and UI resource</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#6-build-the-react-ui" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">6. Build the React UI</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#7-build-and-deploy" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">7. Build and deploy</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#8-connect-to-chatgpt" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">8. Connect to ChatGPT</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#9-play-chess-in-chatgpt" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">9. Play chess in ChatGPT</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#key-concepts" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">Key concepts</span> </a> <ul class="astro-n5w67532" style="--depth: 1;"> <li class="astro-n5w67532" style="--depth: 1;"> <a href="#mcp-server" class="astro-n5w67532" style="--depth: 1;"> <span class="astro-n5w67532" style="--depth: 1;">MCP Server</span> </a> </li><li class="astro-n5w67532" style="--depth: 1;"> <a href="#game-engine-with-agents" class="astro-n5w67532" style="--depth: 1;"> <span class="astro-n5w67532" style="--depth: 1;">Game Engine with Agents</span> </a> </li><li class="astro-n5w67532" style="--depth: 1;"> <a href="#callable-methods" class="astro-n5w67532" style="--depth: 1;"> <span class="astro-n5w67532" style="--depth: 1;">Callable methods</span> </a> </li><li class="astro-n5w67532" style="--depth: 1;"> <a href="#react-integration" class="astro-n5w67532" style="--depth: 1;"> <span class="astro-n5w67532" style="--depth: 1;">React integration</span> </a> </li><li class="astro-n5w67532" style="--depth: 1;"> <a href="#bidirectional-communication" class="astro-n5w67532" style="--depth: 1;"> <span class="astro-n5w67532" style="--depth: 1;">Bidirectional communication</span> </a> </li> </ul> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#next-steps" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">Next steps</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#related-resources" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">Related resources</span> </a> </li> </ul></nav></starlight-toc><script type="module" src="/_astro/TableOfContents.astro_astro_type_script_index_0_lang.FuRcXuRY.js"></script> <div class="mt-6 flex flex-col gap-5 border-t border-[var(--sidebar-border)] pt-6"> <div class="feedback-container"> <script>(()=>{var e=async t=>{await(await t())()};(self.Astro||(self.Astro={})).only=e;window.dispatchEvent(new Event("astro:only"));})();</script><astro-island uid="ZWT1F9" component-url="/_astro/FeedbackPrompt.FVI-KaJz.js" component-export="default" renderer-url="/_astro/client.hmfmp3Nb.js" props="{}" ssr client="only" opts="{"name":"FeedbackPrompt","value":"react"}"></astro-island> </div> <nav class="flex flex-col gap-3" aria-label="Page actions"> <a href="https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/workers/demos/chatgpt-app.mdx" target="_blank" class="group flex items-center gap-2.5 rounded-sm text-[13px] text-[var(--sl-color-gray-2)] transition-colors duration-150 ease-out hover:text-[var(--sl-color-white)] focus-visible:ring-2 focus-visible:ring-[var(--sl-color-text-accent)] focus-visible:outline-none"> <svg aria-hidden="true" class="h-3.5 w-3.5 astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M22 7.24a1 1 0 0 0-.29-.71l-4.24-4.24a1 1 0 0 0-1.1-.22 1 1 0 0 0-.32.22l-2.83 2.83L2.29 16.05a1 1 0 0 0-.29.71V21a1 1 0 0 0 1 1h4.24a1 1 0 0 0 .76-.29l10.87-10.93L21.71 8c.1-.1.17-.2.22-.33a1 1 0 0 0 0-.24v-.14l.07-.05ZM6.83 20H4v-2.83l9.93-9.93 2.83 2.83L6.83 20ZM18.17 8.66l-2.83-2.83 1.42-1.41 2.82 2.82-1.41 1.42Z"/></svg> <span>Edit page</span> </a> <a href="https://github.com/cloudflare/cloudflare-docs/issues/new/choose" target="_blank" class="group flex items-center gap-2.5 rounded-sm text-[13px] text-[var(--sl-color-gray-2)] transition-colors duration-150 ease-out hover:text-[var(--sl-color-white)] focus-visible:ring-2 focus-visible:ring-[var(--sl-color-text-accent)] focus-visible:outline-none"> <svg aria-hidden="true" class="h-3.5 w-3.5 astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M12 .3a12 12 0 0 0-3.8 23.38c.6.12.83-.26.83-.57L9 21.07c-3.34.72-4.04-1.61-4.04-1.61-.55-1.39-1.34-1.76-1.34-1.76-1.08-.74.09-.73.09-.73 1.2.09 1.83 1.24 1.83 1.24 1.08 1.83 2.81 1.3 3.5 1 .1-.78.42-1.31.76-1.61-2.67-.3-5.47-1.33-5.47-5.93 0-1.31.47-2.38 1.24-3.22-.14-.3-.54-1.52.1-3.18 0 0 1-.32 3.3 1.23a11.5 11.5 0 0 1 6 0c2.28-1.55 3.29-1.23 3.29-1.23.64 1.66.24 2.88.12 3.18a4.65 4.65 0 0 1 1.23 3.22c0 4.61-2.8 5.63-5.48 5.92.42.36.81 1.1.81 2.22l-.01 3.29c0 .31.2.69.82.57A12 12 0 0 0 12 .3Z"/></svg> <span>Report issue</span> </a> </nav> </div> </div></div></div> </div> </aside> <div class="main-pane astro-uh4ak5fy"> <main data-pagefind-body class="astro-nezwzdd7" lang="en" dir="ltr"> <div class="content-panel astro-k65j6qoy"> <div class="sl-container astro-k65j6qoy"> <div class="flex items-center justify-between astro-couag5ji"> <astro-breadcrumbs data-main-bem-class="c-breadcrumbs" data-id="breadcrumbs" data-path-length="3" data-truncated="true"> <nav aria-label="breadcrumbs" class="c-breadcrumbs" id="breadcrumbs"> <ol class="c-breadcrumbs__crumbs has-separators"> <li class="c-breadcrumbs__crumb"> <a href="/directory/" class="c-breadcrumbs__link is-index" aria-current="false"> Directory </a> <span class="c-breadcrumbs__separator" aria-hidden="true"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="astro-couag5ji"> <polyline points="9 18 15 12 9 6" class="astro-couag5ji"></polyline> </svg> </span> </li> <li class="c-breadcrumbs__crumb has-ellipsis"> <button type="button" aria-label="Show hidden navigation" class="c-breadcrumbs__truncated-button"> … </button> <span class="c-breadcrumbs__separator" aria-hidden="true"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="astro-couag5ji"> <polyline points="9 18 15 12 9 6" class="astro-couag5ji"></polyline> </svg> </span> </li><li class="c-breadcrumbs__crumb"> <a href="/workers/" class="c-breadcrumbs__link" aria-current="false"> Workers </a> <span class="c-breadcrumbs__separator" aria-hidden="true"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="astro-couag5ji"> <polyline points="9 18 15 12 9 6" class="astro-couag5ji"></polyline> </svg> </span> </li> <li class="c-breadcrumbs__crumb"> <a href="/workers/demos/" class="c-breadcrumbs__link" aria-current="false"> Demos and architectures </a> <span class="c-breadcrumbs__separator" aria-hidden="true"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="astro-couag5ji"> <polyline points="9 18 15 12 9 6" class="astro-couag5ji"></polyline> </svg> </span> </li> <li class="c-breadcrumbs__crumb"> <a href="/workers/demos/chatgpt-app/" class="c-breadcrumbs__link is-current" aria-current="location"> Build an Interactive ChatGPT App </a> </li> </ol> </nav> </astro-breadcrumbs> <script type="application/ld+json">{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/workers/","name":"Workers"}},{"@type":"ListItem","position":3,"item":{"@id":"/workers/demos/","name":"Demos and architectures"}},{"@type":"ListItem","position":4,"item":{"@id":"/workers/demos/chatgpt-app/","name":"Build an Interactive ChatGPT App"}}]}</script> <script type="module">class t extends HTMLElement{constructor(){super(),this.isManualToggle=!1,this.breadcrumbs=null,this.mainBemClass=null,this.totalWidth=0,this.resizeObserver=null,this.handleTruncatedButtonClick=()=>{this.breadcrumbs?.classList.remove("is-truncated"),this.isManualToggle=!0},this.mainBemClass=this.dataset.mainBemClass||null;const e=this.dataset.id;!("truncated"in this.dataset)||!e||(this.breadcrumbs=document.getElementById(e),this.initializeCrumbs(),this.setupResizeObserver())}initializeCrumbs(){this.breadcrumbs?.querySelectorAll(.${this.mainBemClass}__crumb)?.forEach(s=>{this.totalWidth+=s.offsetWidth})}setupResizeObserver(){this.resizeObserver=new ResizeObserver(e=>{e.forEach(s=>{this.checkOverflow(s.target.clientWidth)})}),this.breadcrumbs&&this.resizeObserver.observe(this.breadcrumbs)}connectedCallback(){this.showHiddenCrumbs()}disconnectedCallback(){this.resizeObserver&&this.breadcrumbs&&(this.resizeObserver.unobserve(this.breadcrumbs),this.resizeObserver.disconnect())}toggleTruncated(e){this.breadcrumbs?.classList.toggle("is-truncated",e)}showHiddenCrumbs(){const e=this.breadcrumbs?.querySelector(.${this.mainBemClass}__truncated-button);e?.removeEventListener("click",this.handleTruncatedButtonClick),e?.addEventListener("click",this.handleTruncatedButtonClick.bind(this))}checkOverflow(e){const s=this.totalWidth>e&&!this.isManualToggle;this.toggleTruncated(s),s||(this.isManualToggle=!1)}}customElements.get("astro-breadcrumbs")||customElements.define("astro-breadcrumbs",t);</script> </div> <h1 id="_top" class="astro-k7rnyr65">Build an Interactive ChatGPT App</h1> <div> <span> <strong>Last reviewed: </strong> 7 months ago </span> </div> <div class="page-actions-wrapper astro-couag5ji"> <nav class="page-actions astro-jjhxq4hj" aria-label="Page actions"> <!-- Copy as Markdown --> <button class="not-content astro-jjhxq4hj" id="page-actions-copy" aria-label="Copy Page as Markdown"> <svg class="copy-icon astro-jjhxq4hj" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" viewBox="0 0 256 256" fill="currentColor"><path d="M216,34H88a6,6,0,0,0-6,6V82H40a6,6,0,0,0-6,6V216a6,6,0,0,0,6,6H168a6,6,0,0,0,6-6V174h42a6,6,0,0,0,6-6V40A6,6,0,0,0,216,34ZM162,210H46V94H162Zm48-48H174V88a6,6,0,0,0-6-6H94V46H210Z"/></svg> <svg class="check-icon astro-jjhxq4hj" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" viewBox="0 0 256 256" fill="currentColor"><path d="M172.24,99.76a6,6,0,0,1,0,8.48l-56,56a6,6,0,0,1-8.48,0l-24-24a6,6,0,0,1,8.48-8.48L112,151.51l51.76-51.75A6,6,0,0,1,172.24,99.76ZM230,128A102,102,0,1,1,128,26,102.12,102.12,0,0,1,230,128Zm-12,0a90,90,0,1,0-90,90A90.1,90.1,0,0,0,218,128Z"/></svg> <span class="label-wrap astro-jjhxq4hj"> <span class="label astro-jjhxq4hj">Copy as Markdown</span> <span class="copied-label astro-jjhxq4hj" aria-hidden="true">Copied!</span> </span> </button> <span class="sep astro-jjhxq4hj" aria-hidden="true">|</span> <!-- View as Markdown (anchor so browser opens natively and respects OS color scheme) --> <a class="not-content astro-jjhxq4hj" id="page-actions-view-md" aria-label="View Page as Markdown" href="index.md" target="_blank" rel="noopener noreferrer"> <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" viewBox="0 0 256 256" fill="currentColor" class="astro-jjhxq4hj"><path d="M232,50H24A14,14,0,0,0,10,64V192a14,14,0,0,0,14,14H232a14,14,0,0,0,14-14V64A14,14,0,0,0,232,50Zm2,142a2,2,0,0,1-2,2H24a2,2,0,0,1-2-2V64a2,2,0,0,1,2-2H232a2,2,0,0,1,2,2ZM126,104v48a6,6,0,0,1-12,0V118.49L92.24,140.24a6,6,0,0,1-8.48,0L62,118.49V152a6,6,0,0,1-12,0V104a6,6,0,0,1,10.24-4.24L88,127.51l27.76-27.75A6,6,0,0,1,126,104Zm78.24,19.76a6,6,0,0,1,0,8.48l-24,24a6,6,0,0,1-8.48,0l-24-24a6,6,0,1,1,8.48-8.48L170,137.51V104a6,6,0,0,1,12,0v33.51l13.76-13.75A6,6,0,0,1,204.24,123.76Z"/></svg> <span class="astro-jjhxq4hj">View as Markdown</span> </a> <span class="sep sep-agent-setup astro-jjhxq4hj" aria-hidden="true">|</span> <!-- Agent setup --> <button class="not-content astro-jjhxq4hj" id="page-actions-agent-setup" data-tooltip="Setup your agent to build on Cloudflare" aria-label="Setup your agent to build on Cloudflare"> <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" viewBox="0 0 256 256" fill="currentColor" class="astro-jjhxq4hj"><path d="M200,50H134V16a6,6,0,0,0-12,0V50H56A30,30,0,0,0,26,80V192a30,30,0,0,0,30,30H200a30,30,0,0,0,30-30V80A30,30,0,0,0,200,50Zm18,142a18,18,0,0,1-18,18H56a18,18,0,0,1-18-18V80A18,18,0,0,1,56,62H200a18,18,0,0,1,18,18ZM74,108a10,10,0,1,1,10,10A10,10,0,0,1,74,108Zm88,0a10,10,0,1,1,10,10A10,10,0,0,1,162,108Zm2,30H92a26,26,0,0,0,0,52h72a26,26,0,0,0,0-52Zm-22,12v28H114V150ZM78,164a14,14,0,0,1,14-14h10v28H92A14,14,0,0,1,78,164Zm86,14H154V150h10a14,14,0,0,1,0,28Z"/></svg> <span class="astro-jjhxq4hj">Agent setup</span> </button> <span class="sep sep-docs-for-agents astro-jjhxq4hj" aria-hidden="true">|</span> <!-- Docs for agents --> <button class="not-content astro-jjhxq4hj" id="page-actions-docs-for-agents" data-tooltip="Consume Cloudflare Docs with your agent" aria-label="Consume Cloudflare Docs with your agent"> <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" viewBox="0 0 256 256" fill="currentColor" class="astro-jjhxq4hj"><path d="M98,136a6,6,0,0,1,6-6h64a6,6,0,0,1,0,12H104A6,6,0,0,1,98,136Zm6-26h64a6,6,0,0,0,0-12H104a6,6,0,0,0,0,12Zm126,82a30,30,0,0,1-30,30H88a30,30,0,0,1-30-30V64a18,18,0,0,0-36,0c0,6.76,5.58,11.19,5.64,11.23A6,6,0,1,1,20.4,84.8C20,84.48,10,76.85,10,64A30,30,0,0,1,40,34H176a30,30,0,0,1,30,30V170h10a6,6,0,0,1,3.6,1.2C220,171.52,230,179.15,230,192Zm-124,0c0-6.76-5.59-11.19-5.64-11.23A6,6,0,0,1,104,170h90V64a18,18,0,0,0-18-18H64a29.82,29.82,0,0,1,6,18V192a18,18,0,0,0,36,0Zm112,0a14.94,14.94,0,0,0-4.34-10H115.88A24.83,24.83,0,0,1,118,192a29.87,29.87,0,0,1-6,18h88A18,18,0,0,0,218,192Z"/></svg> <span class="astro-jjhxq4hj">Docs for agents</span> </button> </nav> <script type="module" src="/_astro/PageActions.astro_astro_type_script_index_0_lang.CsW5BfyZ.js"></script> </div> </div> </div> <div class="content-panel astro-k65j6qoy"> <div class="sl-container astro-k65j6qoy"> <starlight-image-zoom> <template class="astro-xymfvnz4"> <dialog class="starlight-image-zoom-dialog astro-xymfvnz4"> <button aria-label="Unzoom image" class="starlight-image-zoom-control astro-xymfvnz4"> <svg aria-hidden="true" fill="currentColor" viewBox="0 0 24 24" class="astro-xymfvnz4"> <use href="#starlight-image-zoom-icon-unzoom" class="astro-xymfvnz4"></use> </svg> </button> <figure class="astro-xymfvnz4"></figure> </dialog> </template> <svg xmlns="http://www.w3.org/2000/svg" style="display:none" class="astro-xymfvnz4"> <symbol id="starlight-image-zoom-icon-zoom" viewBox="0 0 24 24" class="astro-xymfvnz4"> <path d="M9.79 12.79 4 18.59V17a1 1 0 0 0-2 0v4a1 1 0 0 0 .08.38 1 1 0 0 0 .54.54A1 1 0 0 0 3 22h4a1 1 0 0 0 0-2H5.41l5.8-5.79a1 1 0 0 0-1.42-1.42ZM21.92 2.62a1 1 0 0 0-.54-.54A1 1 0 0 0 21 2h-4a1 1 0 0 0 0 2h1.59l-5.8 5.79a1 1 0 0 0 0 1.42 1 1 0 0 0 1.42 0L20 5.41V7a1 1 0 0 0 2 0V3a1 1 0 0 0-.08-.38Z" class="astro-xymfvnz4"></path> </symbol> <symbol id="starlight-image-zoom-icon-unzoom" viewBox="0 0 24 24" class="astro-xymfvnz4"> <path d="M21.71 2.29a1 1 0 0 0-1.42 0l-5.79 5.8V6.5a1 1 0 0 0-2 0v4a1 1 0 0 0 .08.38 1 1 0 0 0 .54.54 1 1 0 0 0 .38.08h4a1 1 0 0 0 0-2h-1.59l5.8-5.79a1 1 0 0 0 0-1.42ZM10.88 12.58a1 1 0 0 0-.38-.08h-4a1 1 0 0 0 0 2h1.59l-5.8 5.79a1 1 0 0 0 0 1.42 1 1 0 0 0 1.42 0l5.79-5.8v1.59a1 1 0 0 0 2 0v-4a1 1 0 0 0-.08-.38 1 1 0 0 0-.54-.54Z" class="astro-xymfvnz4"></path> </symbol> </svg> </starlight-image-zoom> <script type="module" src="/_astro/ImageZoom.astro_astro_type_script_index_0_lang.CZmBqK-T.js"></script> <div class="sl-markdown-content astro-cedpceuv"> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="deploy-your-first-chatgpt-app">Deploy your first ChatGPT App</h2><a class="anchor-link" href="#deploy-your-first-chatgpt-app"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <p>This guide will show you how to build and deploy an interactive ChatGPT App on Cloudflare Workers that can:</p> <ul> <li>Render rich, interactive UI widgets directly in ChatGPT conversations</li> <li>Maintain real-time, multi-user state using Durable Objects</li> <li>Enable bidirectional communication between your app and ChatGPT</li> <li>Build multiplayer experiences that run entirely within ChatGPT</li> </ul> <p>You will build a real-time multiplayer chess game that demonstrates these capabilities. Players can start or join games, make moves on an interactive chessboard, and even ask ChatGPT for strategic advice—all without leaving the conversation.</p> <p>Your ChatGPT App will use the <strong>Model Context Protocol (MCP)</strong> to expose tools and UI resources that ChatGPT can invoke on your behalf.</p> <p>You can view the full code for this example <a href="https://github.com/cloudflare/agents/tree/main/openai-sdk/chess-app" target="_blank" rel="noopener">here<span class="external-link"> ↗</span></a>.</p> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="prerequisites">Prerequisites</h2><a class="anchor-link" href="#prerequisites"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <p>Before you begin, you will need:</p> <ul> <li>A <a href="https://dash.cloudflare.com/sign-up" target="_blank" rel="noopener">Cloudflare account<span class="external-link"> ↗</span></a></li> <li><a href="https://nodejs.org/" target="_blank" rel="noopener">Node.js<span class="external-link"> ↗</span></a> installed (v18 or later)</li> <li>A <a href="https://chat.openai.com/" target="_blank" rel="noopener">ChatGPT Plus or Team account<span class="external-link"> ↗</span></a> with developer mode enabled</li> <li>Basic knowledge of React and TypeScript</li> </ul> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="1-enable-chatgpt-developer-mode">1. Enable ChatGPT Developer Mode</h2><a class="anchor-link" href="#1-enable-chatgpt-developer-mode"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <p>To use ChatGPT Apps (also called connectors), you need to enable developer mode:</p> <ol> <li>Open <a href="https://chat.openai.com/" target="_blank" rel="noopener">ChatGPT<span class="external-link"> ↗</span></a>.</li> <li>Go to <strong>Settings</strong> > <strong>Apps & Connectors</strong> > <strong>Advanced Settings</strong></li> <li>Toggle <strong>Developer mode ON</strong></li> </ol> <p>Once enabled, you will be able to install custom apps during development and testing.</p> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="2-create-your-chatgpt-app-project">2. Create your ChatGPT App project</h2><a class="anchor-link" href="#2-create-your-chatgpt-app-project"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <ol> <li>Create a new project for your Chess App:</li> </ol> <script> if (!customElements.get("lc-pm-restore")) { customElements.define( "lc-pm-restore", class extends HTMLElement { connectedCallback() { const card = this.closest("[data-lc-pm]"); if (!card) return; let saved; try { saved = sessionStorage.getItem("lc-pm-active-tab"); } catch { / storage unavailable / } if (!saved) return; const idx = Number(saved); card.querySelectorAll("[data-lc-pm-tab]").forEach(function (t, i) { t.setAttribute("aria-selected", String(i === idx)); }); card.querySelectorAll("[data-lc-pm-panel]").forEach(function (p, i) { p.hidden = i !== idx; }); } }, ); } </script> <div class="flex w-full flex-col overflow-hidden rounded-lg text-base bg-cl1-gray-9 ring-cl1-gray-8 dark:bg-cl1-gray-0 dark:ring-cl1-gray-2 ring-1 astro-qph66ij4" data-lc-pm> <div class="-my-2 flex items-center gap-1.5 px-2.5 py-[18px] bg-cl1-gray-9 dark:bg-cl1-gray-1 astro-qph66ij4" role="tablist" aria-label="Package manager"> <button role="tab" type="button" aria-selected="true" aria-controls="lc-pm-panel-fus00d-npm" id="lc-pm-tab-fus00d-npm" data-lc-pm-tab class="text-cl1-gray-4 hover:bg-cl1-gray-8 hover:text-cl1-gray-0 aria-selected:bg-cl1-gray-8 aria-selected:text-cl1-gray-0 dark:text-cl1-gray-7 dark:hover:bg-cl1-gray-3 dark:hover:text-cl1-white dark:aria-selected:bg-cl1-gray-3 dark:aria-selected:text-cl1-white focus-visible:outline-cl1-gray-8 dark:focus-visible:outline-cl1-gray-3 m-0 cursor-pointer rounded-md border-0 bg-transparent px-2 py-0.5 text-xs leading-5 font-medium transition-colors focus-visible:outline focus-visible:outline-1 astro-qph66ij4"> npm </button><button role="tab" type="button" aria-selected="false" aria-controls="lc-pm-panel-fus00d-yarn" id="lc-pm-tab-fus00d-yarn" data-lc-pm-tab class="text-cl1-gray-4 hover:bg-cl1-gray-8 hover:text-cl1-gray-0 aria-selected:bg-cl1-gray-8 aria-selected:text-cl1-gray-0 dark:text-cl1-gray-7 dark:hover:bg-cl1-gray-3 dark:hover:text-cl1-white dark:aria-selected:bg-cl1-gray-3 dark:aria-selected:text-cl1-white focus-visible:outline-cl1-gray-8 dark:focus-visible:outline-cl1-gray-3 m-0 cursor-pointer rounded-md border-0 bg-transparent px-2 py-0.5 text-xs leading-5 font-medium transition-colors focus-visible:outline focus-visible:outline-1 astro-qph66ij4"> yarn </button><button role="tab" type="button" aria-selected="false" aria-controls="lc-pm-panel-fus00d-pnpm" id="lc-pm-tab-fus00d-pnpm" data-lc-pm-tab class="text-cl1-gray-4 hover:bg-cl1-gray-8 hover:text-cl1-gray-0 aria-selected:bg-cl1-gray-8 aria-selected:text-cl1-gray-0 dark:text-cl1-gray-7 dark:hover:bg-cl1-gray-3 dark:hover:text-cl1-white dark:aria-selected:bg-cl1-gray-3 dark:aria-selected:text-cl1-white focus-visible:outline-cl1-gray-8 dark:focus-visible:outline-cl1-gray-3 m-0 cursor-pointer rounded-md border-0 bg-transparent px-2 py-0.5 text-xs leading-5 font-medium transition-colors focus-visible:outline focus-visible:outline-1 astro-qph66ij4"> pnpm </button> </div> <div role="tabpanel" id="lc-pm-panel-fus00d-npm" aria-labelledby="lc-pm-tab-fus00d-npm" data-lc-pm-panel class="bg-cl1-white ring-cl1-gray-8 dark:bg-cl1-gray-2 dark:ring-cl1-gray-3 m-0 overflow-hidden rounded-lg ring-1 astro-qph66ij4"> <div class="flex items-stretch astro-qph66ij4"> <pre class="my-0 min-w-0 grow overflow-x-auto border-0 bg-transparent px-4 py-3 text-sm leading-relaxed whitespace-pre astro-qph66ij4"><code data-lc-pm-code class="astro-qph66ij4"><span style="--0:#57C78F;--1:#00783C" class="astro-qph66ij4">npm</span><span style="--0:#FDDA68;--1:#A84E00" class="astro-qph66ij4"> create cloudflare@latest -- my-chess-app</span></code></pre> <button type="button" data-lc-pm-copy data-command="npm create cloudflare@latest -- my-chess-app" aria-label="Copy to clipboard" class="border-cl1-gray-8 text-cl1-gray-4 hover:bg-cl1-gray-8/20 hover:text-cl1-gray-2 focus-visible:ring-cl1-gray-8 dark:border-cl1-gray-3 dark:text-cl1-gray-7 dark:hover:bg-cl1-gray-7/10 dark:hover:text-cl1-gray-8 dark:focus-visible:ring-cl1-gray-3 m-0 flex shrink-0 cursor-pointer items-center justify-center border-0 border-l border-solid bg-transparent px-3 transition-colors focus-visible:ring-1 focus-visible:outline-none focus-visible:ring-inset astro-qph66ij4"> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" viewBox="0 0 256 256" class="astro-qph66ij4"> <path d="M216,32H88a8,8,0,0,0-8,8V80H40a8,8,0,0,0-8,8V216a8,8,0,0,0,8,8H168a8,8,0,0,0,8-8V176h40a8,8,0,0,0,8-8V40A8,8,0,0,0,216,32ZM160,208H48V96H160Zm48-48H176V88a8,8,0,0,0-8-8H96V48H208Z" class="astro-qph66ij4"></path> </svg> </button> </div> </div><div role="tabpanel" id="lc-pm-panel-fus00d-yarn" aria-labelledby="lc-pm-tab-fus00d-yarn" hidden data-lc-pm-panel class="bg-cl1-white ring-cl1-gray-8 dark:bg-cl1-gray-2 dark:ring-cl1-gray-3 m-0 overflow-hidden rounded-lg ring-1 astro-qph66ij4"> <div class="flex items-stretch astro-qph66ij4"> <pre class="my-0 min-w-0 grow overflow-x-auto border-0 bg-transparent px-4 py-3 text-sm leading-relaxed whitespace-pre astro-qph66ij4"><code data-lc-pm-code class="astro-qph66ij4"><span style="--0:#57C78F;--1:#00783C" class="astro-qph66ij4">yarn</span><span style="--0:#FDDA68;--1:#A84E00" class="astro-qph66ij4"> create cloudflare my-chess-app</span></code></pre> <button type="button" data-lc-pm-copy data-command="yarn create cloudflare my-chess-app" aria-label="Copy to clipboard" class="border-cl1-gray-8 text-cl1-gray-4 hover:bg-cl1-gray-8/20 hover:text-cl1-gray-2 focus-visible:ring-cl1-gray-8 dark:border-cl1-gray-3 dark:text-cl1-gray-7 dark:hover:bg-cl1-gray-7/10 dark:hover:text-cl1-gray-8 dark:focus-visible:ring-cl1-gray-3 m-0 flex shrink-0 cursor-pointer items-center justify-center border-0 border-l border-solid bg-transparent px-3 transition-colors focus-visible:ring-1 focus-visible:outline-none focus-visible:ring-inset astro-qph66ij4"> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" viewBox="0 0 256 256" class="astro-qph66ij4"> <path d="M216,32H88a8,8,0,0,0-8,8V80H40a8,8,0,0,0-8,8V216a8,8,0,0,0,8,8H168a8,8,0,0,0,8-8V176h40a8,8,0,0,0,8-8V40A8,8,0,0,0,216,32ZM160,208H48V96H160Zm48-48H176V88a8,8,0,0,0-8-8H96V48H208Z" class="astro-qph66ij4"></path> </svg> </button> </div> </div><div role="tabpanel" id="lc-pm-panel-fus00d-pnpm" aria-labelledby="lc-pm-tab-fus00d-pnpm" hidden data-lc-pm-panel class="bg-cl1-white ring-cl1-gray-8 dark:bg-cl1-gray-2 dark:ring-cl1-gray-3 m-0 overflow-hidden rounded-lg ring-1 astro-qph66ij4"> <div class="flex items-stretch astro-qph66ij4"> <pre class="my-0 min-w-0 grow overflow-x-auto border-0 bg-transparent px-4 py-3 text-sm leading-relaxed whitespace-pre astro-qph66ij4"><code data-lc-pm-code class="astro-qph66ij4"><span style="--0:#57C78F;--1:#00783C" class="astro-qph66ij4">pnpm</span><span style="--0:#FDDA68;--1:#A84E00" class="astro-qph66ij4"> create cloudflare@latest my-chess-app</span></code></pre> <button type="button" data-lc-pm-copy data-command="pnpm create cloudflare@latest my-chess-app" aria-label="Copy to clipboard" class="border-cl1-gray-8 text-cl1-gray-4 hover:bg-cl1-gray-8/20 hover:text-cl1-gray-2 focus-visible:ring-cl1-gray-8 dark:border-cl1-gray-3 dark:text-cl1-gray-7 dark:hover:bg-cl1-gray-7/10 dark:hover:text-cl1-gray-8 dark:focus-visible:ring-cl1-gray-3 m-0 flex shrink-0 cursor-pointer items-center justify-center border-0 border-l border-solid bg-transparent px-3 transition-colors focus-visible:ring-1 focus-visible:outline-none focus-visible:ring-inset astro-qph66ij4"> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" viewBox="0 0 256 256" class="astro-qph66ij4"> <path d="M216,32H88a8,8,0,0,0-8,8V80H40a8,8,0,0,0-8,8V216a8,8,0,0,0,8,8H168a8,8,0,0,0,8-8V176h40a8,8,0,0,0,8-8V40A8,8,0,0,0,216,32ZM160,208H48V96H160Zm48-48H176V88a8,8,0,0,0-8-8H96V48H208Z" class="astro-qph66ij4"></path> </svg> </button> </div> </div> <lc-pm-restore style="display:contents" class="astro-qph66ij4"></lc-pm-restore> </div> <script type="module" src="/_astro/PackageManagers.astro_astro_type_script_index_0_lang.unqpOpS3.js"></script> <ol start="2"> <li>Navigate into your project:</li> </ol> <div class="expressive-code"><link rel="stylesheet" href="/_astro/ec.7rqu9.css"><script type="module" src="/_astro/ec.0vx5m.js"></script><figure class="frame is-terminal not-content"><figcaption class="header"><span class="title"></span><span class="sr-only">Terminal window</span></figcaption><pre data-language="sh"><code><div class="ec-line"><div class="code"><span style="--0:#57C78F;--1:#00783C">cd</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">my-chess-app</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="cd my-chess-app"><div></div></button></div></figure></div> <ol start="3"> <li>Install the required dependencies:</li> </ol> <div class="expressive-code"><figure class="frame is-terminal not-content"><figcaption class="header"><span class="title"></span><span class="sr-only">Terminal window</span></figcaption><pre data-language="sh"><code><div class="ec-line"><div class="code"><span style="--0:#57C78F;--1:#00783C">npm</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">install</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">agents</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">@modelcontextprotocol/sdk</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">chess.js</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">react</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">react-dom</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">react-chessboard</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="npm install agents @modelcontextprotocol/sdk chess.js react react-dom react-chessboard"><div></div></button></div></figure></div> <ol start="4"> <li>Install development dependencies:</li> </ol> <div class="expressive-code"><figure class="frame is-terminal not-content"><figcaption class="header"><span class="title"></span><span class="sr-only">Terminal window</span></figcaption><pre data-language="sh"><code><div class="ec-line"><div class="code"><span style="--0:#57C78F;--1:#00783C">npm</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">install</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">-D</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">@cloudflare/vite-plugin</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">@vitejs/plugin-react</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">vite</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">vite-plugin-singlefile</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">@types/react</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">@types/react-dom</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="npm install -D @cloudflare/vite-plugin @vitejs/plugin-react vite vite-plugin-singlefile @types/react @types/react-dom"><div></div></button></div></figure></div> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="3-configure-your-project">3. Configure your project</h2><a class="anchor-link" href="#3-configure-your-project"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <ol> <li>Update your <code dir="auto">wrangler.jsonc</code> to configure Durable Objects and assets:</li> </ol> <script> (() => { class StarlightTabsRestore extends HTMLElement { connectedCallback() { const starlightTabs = this.closest('starlight-tabs'); if (!(starlightTabs instanceof HTMLElement) || typeof localStorage === 'undefined') return; const syncKey = starlightTabs.dataset.syncKey; if (!syncKey) return; const label = localStorage.getItem(starlight-synced-tabs__${syncKey}); if (!label) return; const tabs = [...starlightTabs?.querySelectorAll('[role="tab"]')]; const tabIndexToRestore = tabs.findIndex( (tab) => tab instanceof HTMLAnchorElement && tab.textContent?.trim() === label ); const panels = starlightTabs?.querySelectorAll(':scope > [role="tabpanel"]'); const newTab = tabs[tabIndexToRestore]; const newPanel = panels[tabIndexToRestore]; if (tabIndexToRestore < 1 || !newTab || !newPanel) return; tabs[0]?.setAttribute('aria-selected', 'false'); tabs[0]?.setAttribute('tabindex', '-1'); panels?.[0]?.setAttribute('hidden', 'true'); newTab.removeAttribute('tabindex'); newTab.setAttribute('aria-selected', 'true'); newPanel.removeAttribute('hidden'); } } customElements.define('starlight-tabs-restore', StarlightTabsRestore); })() </script><starlight-tabs data-sync-key="wranglerConfig" class="astro-6ilsj7c3"> <div class="tablist-wrapper not-content astro-6ilsj7c3"> <ul role="tablist" class="astro-6ilsj7c3"> <li role="presentation" class="tab astro-6ilsj7c3"> <a role="tab" href="#tab-panel-11290" id="tab-11290" aria-selected="true" tabindex="0" class="astro-6ilsj7c3"> <svg aria-hidden="true" class="astro-6ilsj7c3 astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M0.734 13.269L0.562 10.732Q1.938 10.732 2.497 10.087L2.497 10.087Q2.884 9.614 2.884 8.711L2.884 8.711Q2.884 8.324 2.798 7.571Q2.712 6.819 2.712 6.410Q2.712 6.002 2.669 5.185L2.669 5.185Q2.583 4.454 2.583 4.153L2.583 4.153Q2.583 2.089 3.787 1.099Q4.991 0.111 7.184 0.111L7.184 0.111L8.259 0.111L8.259 2.648L7.700 2.648Q6.754 2.648 6.345 3.185Q5.937 3.723 5.937 4.798L5.937 4.798Q5.937 5.056 6.023 5.572L6.023 5.572Q6.109 6.217 6.109 6.561L6.109 6.561Q6.109 6.819 6.152 7.378L6.152 7.378Q6.238 8.152 6.238 8.582L6.238 8.582Q6.238 10.216 5.550 11.033L5.550 11.033Q4.948 11.764 3.658 12.065L3.658 12.065Q4.948 12.409 5.550 13.097L5.550 13.097Q6.238 13.957 6.238 15.548L6.238 15.548Q6.238 16.021 6.152 16.795L6.152 16.795Q6.066 17.354 6.088 17.612Q6.109 17.870 6.023 18.515L6.023 18.515Q5.937 18.988 5.937 19.203L5.937 19.203Q5.937 20.278 6.345 20.815Q6.754 21.353 7.700 21.353L7.700 21.353L8.259 21.353L8.259 23.890L7.184 23.890Q2.712 23.890 2.712 19.848L2.712 19.848Q2.712 18.386 2.862 17.590Q3.013 16.795 3.013 15.290L3.013 15.290Q3.013 13.269 0.734 13.269L0.734 13.269ZM23.438 10.732L23.438 13.011Q21.159 13.011 21.159 15.032L21.159 15.032Q21.159 15.419 21.224 16.171Q21.288 16.924 21.288 17.311L21.288 17.311Q21.417 18.128 21.417 19.590L21.417 19.590Q21.417 23.632 16.859 23.632L16.859 23.632L15.784 23.632L15.784 21.353L16.300 21.353Q17.246 21.353 17.654 20.815Q18.063 20.278 18.063 19.203Q18.063 18.128 17.934 17.569L17.934 17.569Q17.934 17.225 17.848 16.558Q17.762 15.892 17.762 15.548L17.762 15.548Q17.762 13.957 18.450 13.097L18.450 13.097Q19.052 12.409 20.342 12.065L20.342 12.065Q19.052 11.764 18.450 11.033L18.450 11.033Q17.762 10.216 17.762 8.582L17.762 8.582Q17.762 8.152 17.848 7.378L17.848 7.378Q17.934 6.819 17.934 6.561L17.934 6.561Q18.063 5.873 18.063 4.841Q18.063 3.809 17.633 3.293Q17.203 2.777 16.300 2.648L16.300 2.648L15.784 2.648L15.784 0.111L16.859 0.111Q19.009 0.111 20.213 1.099Q21.417 2.089 21.417 4.153L21.417 4.153Q21.417 4.540 21.352 5.292Q21.288 6.045 21.288 6.432L21.288 6.432Q21.159 7.249 21.116 8.711L21.116 8.711Q21.159 9.614 21.503 10.087L21.503 10.087Q22.062 10.732 23.438 10.732L23.438 10.732Z"/></svg> wrangler.jsonc </a> </li><li role="presentation" class="tab astro-6ilsj7c3"> <a role="tab" href="#tab-panel-11291" id="tab-11291" aria-selected="false" tabindex="-1" class="astro-6ilsj7c3"> <svg aria-hidden="true" class="astro-6ilsj7c3 astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="m21.32 9.55-1.89-.63.89-1.78A1 1 0 0 0 20.13 6L18 3.87a1 1 0 0 0-1.15-.19l-1.78.89-.63-1.89A1 1 0 0 0 13.5 2h-3a1 1 0 0 0-.95.68l-.63 1.89-1.78-.89A1 1 0 0 0 6 3.87L3.87 6a1 1 0 0 0-.19 1.15l.89 1.78-1.89.63a1 1 0 0 0-.68.94v3a1 1 0 0 0 .68.95l1.89.63-.89 1.78A1 1 0 0 0 3.87 18L6 20.13a1 1 0 0 0 1.15.19l1.78-.89.63 1.89a1 1 0 0 0 .95.68h3a1 1 0 0 0 .95-.68l.63-1.89 1.78.89a1 1 0 0 0 1.13-.19L20.13 18a1 1 0 0 0 .19-1.15l-.89-1.78 1.89-.63a1 1 0 0 0 .68-.94v-3a1 1 0 0 0-.68-.95ZM20 12.78l-1.2.4A2 2 0 0 0 17.64 16l.57 1.14-1.1 1.1-1.11-.6a2 2 0 0 0-2.79 1.16l-.4 1.2h-1.59l-.4-1.2A2 2 0 0 0 8 17.64l-1.14.57-1.1-1.1.6-1.11a2 2 0 0 0-1.16-2.82l-1.2-.4v-1.56l1.2-.4A2 2 0 0 0 6.36 8l-.57-1.11 1.1-1.1L8 6.36a2 2 0 0 0 2.82-1.16l.4-1.2h1.56l.4 1.2A2 2 0 0 0 16 6.36l1.14-.57 1.1 1.1-.6 1.11a2 2 0 0 0 1.16 2.79l1.2.4v1.59ZM12 8a4 4 0 1 0 0 8 4 4 0 0 0 0-8Zm0 6a2 2 0 1 1 0-4 2 2 0 0 1 0 4Z"/></svg> wrangler.toml </a> </li> </ul> </div> <div id="tab-panel-11290" aria-labelledby="tab-11290" role="tabpanel"> <div class="expressive-code"><link rel="stylesheet" href="/_astro/ec.7rqu9.css"><script type="module" src="/_astro/ec.0vx5m.js"></script><figure class="frame has-title not-content"><figcaption class="header"><span class="title">JSONC</span></figcaption><pre data-language="jsonc"><code><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#C895EA;--1:#7C5B92">name</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"my-chess-app"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#C895EA;--1:#7C5B92">main</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"src/index.ts"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic">// Set this to today's date</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#C895EA;--1:#7C5B92">compatibility_date</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"2026-06-10"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#C895EA;--1:#7C5B92">compatibility_flags</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">[</span><span style="--0:#FDDA68;--1:#A84E00">"nodejs_compat"</span><span style="--0:#89DDFF;--1:#007474">],</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#C895EA;--1:#7C5B92">durable_objects</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#FFCB6B;--1:#7E6435">bindings</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">[</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#F78C6C;--1:#985643">name</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"CHESS"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#F78C6C;--1:#985643">class_name</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"ChessGame"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">],</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#C895EA;--1:#7C5B92">migrations</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">[</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#FFCB6B;--1:#7E6435">tag</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"v1"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#FFCB6B;--1:#7E6435">new_sqlite_classes</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">[</span><span style="--0:#FDDA68;--1:#A84E00">"ChessGame"</span><span style="--0:#89DDFF;--1:#007474">],</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">],</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#C895EA;--1:#7C5B92">assets</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#FFCB6B;--1:#7E6435">directory</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"dist"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#FFCB6B;--1:#7E6435">binding</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"ASSETS"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">}</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="{ "name": "my-chess-app", "main": "src/index.ts", // Set this to today's date "compatibility_date": "2026-06-10", "compatibility_flags": ["nodejs_compat"], "durable_objects": { "bindings": [ { "name": "CHESS", "class_name": "ChessGame", }, ], }, "migrations": [ { "tag": "v1", "new_sqlite_classes": ["ChessGame"], }, ], "assets": { "directory": "dist", "binding": "ASSETS", },}"><div></div></button></div><div class="explain"><button class="explain-button" type="button" data-explain-code="" aria-label="Explain Code"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"></path><path d="M20 3v4"></path><path d="M22 5h-4"></path><path d="M4 17v2"></path><path d="M5 18H3"></path></svg></button></div></figure></div> </div> <div id="tab-panel-11291" aria-labelledby="tab-11291" role="tabpanel" hidden> <div class="expressive-code"><figure class="frame has-title not-content"><figcaption class="header"><span class="title">TOML</span></figcaption><pre data-language="toml"><code><div class="ec-line"><div class="code"><span style="--0:#EEFFFF;--1:#00268F">name</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"my-chess-app"</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EEFFFF;--1:#00268F">main</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"src/index.ts"</span></div></div><div class="ec-line"><div class="code"><span style="--0:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic"># Set this to today's date</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EEFFFF;--1:#00268F">compatibility_date</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"2026-06-10"</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EEFFFF;--1:#00268F">compatibility_flags</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">[</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"nodejs_compat"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">]</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">[[</span><span style="--0:#57C78F;--1:#00783C">durable_objects</span><span style="--0:#EEFFFF;--1:#62676A">.</span><span style="--0:#57C78F;--1:#00783C">bindings</span><span style="--0:#89DDFF;--1:#007474">]]</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EEFFFF;--1:#00268F">name</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"CHESS"</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EEFFFF;--1:#00268F">class_name</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"ChessGame"</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">[[</span><span style="--0:#57C78F;--1:#00783C">migrations</span><span style="--0:#89DDFF;--1:#007474">]]</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EEFFFF;--1:#00268F">tag</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"v1"</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EEFFFF;--1:#00268F">new_sqlite_classes</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">[</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"ChessGame"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">]</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">[</span><span style="--0:#57C78F;--1:#00783C">assets</span><span style="--0:#89DDFF;--1:#007474">]</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EEFFFF;--1:#00268F">directory</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"dist"</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EEFFFF;--1:#00268F">binding</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"ASSETS"</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="name = "my-chess-app"main = "src/index.ts"# Set this to today's datecompatibility_date = "2026-06-10"compatibility_flags = [ "nodejs_compat" ][[durable_objects.bindings]]name = "CHESS"class_name = "ChessGame"[[migrations]]tag = "v1"new_sqlite_classes = [ "ChessGame" ][assets]directory = "dist"binding = "ASSETS""><div></div></button></div><div class="explain"><button class="explain-button" type="button" data-explain-code="" aria-label="Explain Code"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"></path><path d="M20 3v4"></path><path d="M22 5h-4"></path><path d="M4 17v2"></path><path d="M5 18H3"></path></svg></button></div></figure></div> </div> <starlight-tabs-restore class="astro-6ilsj7c3"></starlight-tabs-restore> </starlight-tabs> <script type="module">class r extends HTMLElement{static#e=new Map;#t;#n="starlight-synced-tabs__";constructor(){super();const t=this.querySelector('[role="tablist"]');if(this.tabs=[...t.querySelectorAll('[role="tab"]')],this.panels=[...this.querySelectorAll(':scope > [role="tabpanel"]')],this.#t=this.dataset.syncKey,this.#t){const i=r.#e.get(this.#t)??[];i.push(this),r.#e.set(this.#t,i)}this.tabs.forEach((i,c)=>{i.addEventListener("click",e=>{e.preventDefault();const n=t.querySelector('[aria-selected="true"]');e.currentTarget!==n&&this.switchTab(e.currentTarget,c)}),i.addEventListener("keydown",e=>{const n=this.tabs.indexOf(e.currentTarget),s=e.key==="ArrowLeft"?n-1:e.key==="ArrowRight"?n+1:e.key==="Home"?0:e.key==="End"?this.tabs.length-1:null;s!==null&&this.tabs[s]&&(e.preventDefault(),this.switchTab(this.tabs[s],s))})})}switchTab(t,i,c=!0){if(!t)return;const e=c?this.getBoundingClientRect().top:0;this.tabs.forEach(s=>{s.setAttribute("aria-selected","false"),s.setAttribute("tabindex","-1")}),this.panels.forEach(s=>{s.hidden=!0});const n=this.panels[i];n&&(n.hidden=!1),t.removeAttribute("tabindex"),t.setAttribute("aria-selected","true"),c&&(t.focus(),r.#r(this,t),window.scrollTo({top:window.scrollY+(this.getBoundingClientRect().top-e),behavior:"instant"}))}#i(t){!this.#t||typeof localStorage>"u"||localStorage.setItem(this.#n+this.#t,t)}static#r(t,i){const c=t.#t,e=r.#s(i);if(!c||!e)return;const n=r.#e.get(c);if(n){for(const s of n){if(s===t)continue;const a=s.tabs.findIndex(o=>r.#s(o)===e);a!==-1&&s.switchTab(s.tabs[a],a,!1)}t.#i(e)}}static#s(t){return t.textContent?.trim()}}customElements.define("starlight-tabs",r);</script> <ol start="2"> <li>Create a <code dir="auto">vite.config.ts</code> for building your React UI:</li> </ol> <div class="expressive-code"><figure class="frame has-title not-content"><figcaption class="header"><span class="title">TypeScript</span></figcaption><pre data-language="ts"><code><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">cloudflare</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"@cloudflare/vite-plugin"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--1:#8F1500"><span style="--0:#EE9080">import </span><span style="--0:#D5D7D8">react</span><span style="--0:#EE9080"> from </span></span><span style="--0:#FDDA68;--1:#A84E00">"@vitejs/plugin-react"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">defineConfig</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"vite"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">viteSingleFile</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"vite-plugin-singlefile"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">export</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">default</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">defineConfig</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">plugins</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> [</span><span style="--0:#57C78F;--1:#00783C">react</span><span style="--0:#EEFFFF;--1:#62676A">()</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">cloudflare</span><span style="--0:#EEFFFF;--1:#62676A">()</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">viteSingleFile</span><span style="--0:#EEFFFF;--1:#62676A">()]</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">build</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">minify</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">false</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="import { cloudflare } from "@cloudflare/vite-plugin";import react from "@vitejs/plugin-react";import { defineConfig } from "vite";import { viteSingleFile } from "vite-plugin-singlefile";export default defineConfig({ plugins: [react(), cloudflare(), viteSingleFile()], build: { minify: false, },});"><div></div></button></div><div class="explain"><button class="explain-button" type="button" data-explain-code="" aria-label="Explain Code"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"></path><path d="M20 3v4"></path><path d="M22 5h-4"></path><path d="M4 17v2"></path><path d="M5 18H3"></path></svg></button></div></figure></div> <ol start="3"> <li>Update your <code dir="auto">package.json</code> scripts:</li> </ol> <div class="expressive-code"><figure class="frame not-content"><figcaption class="header"></figcaption><pre data-language="json"><code><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#C895EA;--1:#7C5B92">scripts</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#FFCB6B;--1:#7E6435">dev</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"vite"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#FFCB6B;--1:#7E6435">build</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"vite build"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#FFCB6B;--1:#7E6435">deploy</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"vite build && wrangler deploy"</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">}</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="{ "scripts": { "dev": "vite", "build": "vite build", "deploy": "vite build && wrangler deploy" }}"><div></div></button></div></figure></div> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="4-create-the-chess-game-engine">4. Create the Chess game engine</h2><a class="anchor-link" href="#4-create-the-chess-game-engine"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <ol> <li>Create the game logic using Durable Objects at <code dir="auto">src/chess.tsx</code>:</li> </ol> <div class="expressive-code"><figure class="frame not-content" style="--lnWidth:3ch"><figcaption class="header"></figcaption><pre data-language="tsx"><code><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">Agent</span></span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">callable</span></span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">getCurrentAgent</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"agents"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">Chess</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"chess.js"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">type</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">Color</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"w"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">|</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"b"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">type</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">ConnectionState</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">playerId</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">export</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">type</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">State</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">board</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">players</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--1:#007474"><span style="--0:#EEFFFF"> </span><span style="--0:#89DDFF">{</span><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">w</span><span style="--0:#EE9080;--1:#8F1500">?:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--1:#007474"><span style="--0:#89DDFF">;</span><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">b</span><span style="--0:#EE9080;--1:#8F1500">?:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--1:#007474"><span style="--0:#EEFFFF"> </span><span style="--0:#89DDFF">};</span></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">status</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#FDDA68;--1:#A84E00">"waiting"</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#EE9080;--1:#8F1500">|</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#FDDA68;--1:#A84E00">"active"</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#EE9080;--1:#8F1500">|</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#FDDA68;--1:#A84E00">"mate"</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#EE9080;--1:#8F1500">|</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#FDDA68;--1:#A84E00">"draw"</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#EE9080;--1:#8F1500">|</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#FDDA68;--1:#A84E00">"resigned"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">winner</span><span style="--0:#EE9080;--1:#8F1500">?:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">Color</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">lastSan</span><span style="--0:#EE9080;--1:#8F1500">?:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">export</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">class</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">ChessGame</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">extends</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">Agent</span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#57C78F;--1:#00783C">Env</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">State</span><span style="--0:#89DDFF;--1:#007474">></span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">initialState</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">State</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">board</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">Chess</span><span style="--0:#EEFFFF;--1:#62676A">()</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">fen</span><span style="--0:#EEFFFF;--1:#62676A">()</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">players</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{},</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">status</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"waiting"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">};</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:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">Chess</span><span style="--0:#EEFFFF;--1:#62676A">()</span><span style="--0:#89DDFF;--1:#007474">;</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:#EE9080;--1:#8F1500">constructor</span><span style="--0:#89DDFF;--1:#007474">(</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#B59EE1;--1:#7C008F">ctx</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">DurableObjectState</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">public</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">env</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">Env</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">super</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#D5D7D8;--1:#8F1500">ctx</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">env</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">load</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">board</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</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:#EE9080;--1:#8F1500">private</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">colorOf</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">playerId</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">Color</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">|</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">undefined</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">players</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#EEFFFF;--1:#00268F">players</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">w</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">===</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">playerId</span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"w"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#EEFFFF;--1:#00268F">players</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">b</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">===</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">playerId</span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"b"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">undefined</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</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:#89DDFF;--1:#007474">@</span><span style="--0:#57C78F;--1:#00783C">callable</span><span style="--0:#EEFFFF;--1:#62676A">()</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">join</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">params</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--1:#007474"><span style="--0:#EEFFFF"> </span><span style="--0:#89DDFF">{</span><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">playerId</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--1:#007474"><span style="--0:#89DDFF">;</span><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">preferred</span><span style="--0:#EE9080;--1:#8F1500">?:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">Color</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#EE9080;--1:#8F1500">|</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#FDDA68;--1:#A84E00">"any"</span><span style="--1:#007474"><span style="--0:#EEFFFF"> </span><span style="--0:#89DDFF">})</span></span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">playerId</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">preferred</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"any"</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">params</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">connection</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">getCurrentAgent</span><span style="--0:#EE9080;--1:#32008F">()</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--1:#8F1500"><span style="--0:#EE9080">!</span><span style="--0:#D5D7D8">connection</span></span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#EE9080;--1:#8F1500">throw</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">Error</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#FDDA68;--1:#A84E00">"Not connected"</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</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:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">connection</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">setState</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">playerId</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">s</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#89DDFF;--1:#007474">;</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:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic">// Already seated? Return seat</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">already</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">colorOf</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#D5D7D8;--1:#8F1500">playerId</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#D5D7D8;--1:#8F1500">already</span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> ok</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">true</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> role</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">already</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">as</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">Color</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> state</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">s</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</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:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic">// Choose a seat</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">free</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EE9080;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">Color</span><span style="--0:#EE9080;--1:#007474">[] </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> ([</span><span style="--0:#FDDA68;--1:#A84E00">"w"</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"b"</span><span style="--0:#EE9080;--1:#32008F">] </span><span style="--0:#EE9080;--1:#8F1500">as</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">filter</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">c</span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">!</span><span style="--0:#EEFFFF;--1:#00268F">s</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">players</span><span style="--0:#EE9080;--1:#32008F">[</span><span style="--0:#D5D7D8;--1:#8F1500">c</span><span style="--0:#EE9080;--1:#32008F">])</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#EEFFFF;--1:#00268F">free</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#9D5600">length</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">===</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">0</span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> ok</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">true</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> role</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"spectator"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">as</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> state</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">s</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</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:#EE9080;--1:#8F1500">let</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--1:#8F1500"><span style="--0:#D5D7D8">seat</span><span style="--0:#EE9080">:</span></span><span style="--0:#EE9080;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">Color</span><span style="--0:#EE9080;--1:#007474"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">free</span><span style="--0:#EE9080;--1:#32008F">[</span><span style="--0:#B59EE1;--1:#7C008F">0</span><span style="--0:#EE9080;--1:#32008F">]</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#D5D7D8;--1:#8F1500">preferred</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">===</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"w"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">&&</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EEFFFF;--1:#00268F">free</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">includes</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#FDDA68;--1:#A84E00">"w"</span><span style="--0:#EEFFFF;--1:#62676A">)) </span><span style="--0:#D5D7D8;--1:#8F1500">seat</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"w"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#D5D7D8;--1:#8F1500">preferred</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">===</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"b"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">&&</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EEFFFF;--1:#00268F">free</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">includes</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#FDDA68;--1:#A84E00">"b"</span><span style="--0:#EEFFFF;--1:#62676A">)) </span><span style="--0:#D5D7D8;--1:#8F1500">seat</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"b"</span><span style="--0:#89DDFF;--1:#007474">;</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:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">s</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">players</span><span style="--0:#EEFFFF;--1:#62676A">[</span><span style="--0:#D5D7D8;--1:#8F1500">seat</span><span style="--0:#EEFFFF;--1:#62676A">] </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">playerId</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">s</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">status</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EEFFFF;--1:#00268F">s</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">players</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">w</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">&&</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EEFFFF;--1:#00268F">s</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">players</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">b</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">?</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"active"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"waiting"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">setState</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#D5D7D8;--1:#8F1500">s</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> ok</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">true</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> role</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">seat</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> state</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">s</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</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:#89DDFF;--1:#007474">@</span><span style="--0:#57C78F;--1:#00783C">callable</span><span style="--0:#EEFFFF;--1:#62676A">()</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">move</span><span style="--0:#89DDFF;--1:#007474">(</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#B59EE1;--1:#7C008F">move</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--1:#007474"><span style="--0:#EEFFFF"> </span><span style="--0:#89DDFF">{</span><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">from</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--1:#007474"><span style="--0:#89DDFF">;</span><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">to</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--1:#007474"><span style="--0:#89DDFF">;</span><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">promotion</span><span style="--0:#EE9080;--1:#8F1500">?:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--1:#007474"><span style="--0:#EEFFFF"> </span><span style="--0:#89DDFF">},</span></span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#B59EE1;--1:#7C008F">expectedFen</span><span style="--0:#EE9080;--1:#8F1500">?:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">status</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">===</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"waiting"</span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">ok</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">false</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">reason</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"not-in-game"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">fen</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">fen</span><span style="--0:#EEFFFF;--1:#62676A">()</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">status</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">status</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</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:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">connection</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">getCurrentAgent</span><span style="--0:#EE9080;--1:#32008F">()</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--1:#8F1500"><span style="--0:#EE9080">!</span><span style="--0:#D5D7D8">connection</span></span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#EE9080;--1:#8F1500">throw</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">Error</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#FDDA68;--1:#A84E00">"Not connected"</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">playerId</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">connection</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">as</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">ConnectionState</span><span style="--0:#89DDFF;--1:#007474">;</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:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">seat</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">colorOf</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#D5D7D8;--1:#8F1500">playerId</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--1:#8F1500"><span style="--0:#EE9080">!</span><span style="--0:#D5D7D8">seat</span></span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">ok</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">false</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">reason</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"not-in-game"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">fen</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">fen</span><span style="--0:#EEFFFF;--1:#62676A">()</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">status</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">status</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</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:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#D5D7D8;--1:#8F1500">seat</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">!==</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">turn</span><span style="--0:#EEFFFF;--1:#62676A">()) </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">ok</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">false</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">reason</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"not-your-turn"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">fen</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">fen</span><span style="--0:#EEFFFF;--1:#62676A">()</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">status</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">status</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</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:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic">// Optimistic sync guard</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#D5D7D8;--1:#8F1500">expectedFen</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">&&</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">expectedFen</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">!==</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">fen</span><span style="--0:#EEFFFF;--1:#62676A">()) </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">ok</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">false</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">reason</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"stale"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">fen</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">fen</span><span style="--0:#EEFFFF;--1:#62676A">()</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">status</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">status</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</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:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">res</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">move</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#D5D7D8;--1:#8F1500">move</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--1:#8F1500"><span style="--0:#EE9080">!</span><span style="--0:#D5D7D8">res</span></span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">ok</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">false</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">reason</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"illegal"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">fen</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">fen</span><span style="--0:#EEFFFF;--1:#62676A">()</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">status</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">status</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</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:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">fen</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">fen</span><span style="--0:#EE9080;--1:#32008F">()</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">let</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--1:#8F1500"><span style="--0:#D5D7D8">status</span><span style="--0:#EE9080">:</span></span><span style="--0:#EE9080;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">State</span><span style="--0:#EE9080;--1:#007474">[</span><span style="--0:#FDDA68;--1:#A84E00">"status"</span><span style="--0:#EE9080;--1:#007474">] </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"active"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">isCheckmate</span><span style="--0:#EEFFFF;--1:#62676A">()) </span><span style="--0:#D5D7D8;--1:#8F1500">status</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"mate"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">else</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">isDraw</span><span style="--0:#EEFFFF;--1:#62676A">()) </span><span style="--0:#D5D7D8;--1:#8F1500">status</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"draw"</span><span style="--0:#89DDFF;--1:#007474">;</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:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">setState</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">...</span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">board</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">fen</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">lastSan</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EEFFFF;--1:#00268F">res</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">san</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#D5D7D8;--1:#8F1500">status</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">winner</span><span style="--0:#89DDFF;--1:#007474">:</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#D5D7D8;--1:#8F1500">status</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">===</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"mate"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">?</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">turn</span><span style="--0:#EEFFFF;--1:#62676A">() </span><span style="--0:#EE9080;--1:#8F1500">===</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"w"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">?</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"b"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"w"</span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">undefined</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</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:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> ok</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">true</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">fen</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> san</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EEFFFF;--1:#00268F">res</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">san</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">status</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</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:#89DDFF;--1:#007474">@</span><span style="--0:#57C78F;--1:#00783C">callable</span><span style="--0:#EEFFFF;--1:#62676A">()</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">resign</span><span style="--0:#89DDFF;--1:#007474">()</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">connection</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">getCurrentAgent</span><span style="--0:#EE9080;--1:#32008F">()</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--1:#8F1500"><span style="--0:#EE9080">!</span><span style="--0:#D5D7D8">connection</span></span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#EE9080;--1:#8F1500">throw</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">Error</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#FDDA68;--1:#A84E00">"Not connected"</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">playerId</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">connection</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">as</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">ConnectionState</span><span style="--0:#89DDFF;--1:#007474">;</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:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">seat</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">colorOf</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#D5D7D8;--1:#8F1500">playerId</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--1:#8F1500"><span style="--0:#EE9080">!</span><span style="--0:#D5D7D8">seat</span></span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> ok</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">false</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> reason</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"not-in-game"</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> state</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">};</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:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">winner</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">seat</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">===</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"w"</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">?</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"b"</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"w"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">setState</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">...</span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> status</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"resigned"</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">winner</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> ok</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">true</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> state</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">}</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="import { Agent, callable, getCurrentAgent } from "agents";import { Chess } from "chess.js";type Color = "w" | "b";type ConnectionState = { playerId: string;};export type State = { board: string; players: { w?: string; b?: string }; status: "waiting" | "active" | "mate" | "draw" | "resigned"; winner?: Color; lastSan?: string;};export class ChessGame extends Agent<Env, State> { initialState: State = { board: new Chess().fen(), players: {}, status: "waiting", }; game = new Chess(); constructor( ctx: DurableObjectState, public env: Env, ) { super(ctx, env); this.game.load(this.state.board); } private colorOf(playerId: string): Color | undefined { const { players } = this.state; if (players.w === playerId) return "w"; if (players.b === playerId) return "b"; return undefined; } @callable() join(params: { playerId: string; preferred?: Color | "any" }) { const { playerId, preferred = "any" } = params; const { connection } = getCurrentAgent(); if (!connection) throw new Error("Not connected"); connection.setState({ playerId }); const s = this.state; // Already seated? Return seat const already = this.colorOf(playerId); if (already) { return { ok: true, role: already as Color, state: s }; } // Choose a seat const free: Color[] = (["w", "b"] as const).filter((c) => !s.players[c]); if (free.length === 0) { return { ok: true, role: "spectator" as const, state: s }; } let seat: Color = free[0]; if (preferred === "w" && free.includes("w")) seat = "w"; if (preferred === "b" && free.includes("b")) seat = "b"; s.players[seat] = playerId; s.status = s.players.w && s.players.b ? "active" : "waiting"; this.setState(s); return { ok: true, role: seat, state: s }; } @callable() move( move: { from: string; to: string; promotion?: string }, expectedFen?: string, ) { if (this.state.status === "waiting") { return { ok: false, reason: "not-in-game", fen: this.game.fen(), status: this.state.status, }; } const { connection } = getCurrentAgent(); if (!connection) throw new Error("Not connected"); const { playerId } = connection.state as ConnectionState; const seat = this.colorOf(playerId); if (!seat) { return { ok: false, reason: "not-in-game", fen: this.game.fen(), status: this.state.status, }; } if (seat !== this.game.turn()) { return { ok: false, reason: "not-your-turn", fen: this.game.fen(), status: this.state.status, }; } // Optimistic sync guard if (expectedFen && expectedFen !== this.game.fen()) { return { ok: false, reason: "stale", fen: this.game.fen(), status: this.state.status, }; } const res = this.game.move(move); if (!res) { return { ok: false, reason: "illegal", fen: this.game.fen(), status: this.state.status, }; } const fen = this.game.fen(); let status: State["status"] = "active"; if (this.game.isCheckmate()) status = "mate"; else if (this.game.isDraw()) status = "draw"; this.setState({ ...this.state, board: fen, lastSan: res.san, status, winner: status === "mate" ? (this.game.turn() === "w" ? "b" : "w") : undefined, }); return { ok: true, fen, san: res.san, status }; } @callable() resign() { const { connection } = getCurrentAgent(); if (!connection) throw new Error("Not connected"); const { playerId } = connection.state as ConnectionState; const seat = this.colorOf(playerId); if (!seat) return { ok: false, reason: "not-in-game", state: this.state }; const winner = seat === "w" ? "b" : "w"; this.setState({ ...this.state, status: "resigned", winner }); return { ok: true, state: this.state }; }}"><div></div></button></div><div class="explain"><button class="explain-button" type="button" data-explain-code="" aria-label="Explain Code"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"></path><path d="M20 3v4"></path><path d="M22 5h-4"></path><path d="M4 17v2"></path><path d="M5 18H3"></path></svg></button></div></figure></div> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="5-create-the-mcp-server-and-ui-resource">5. Create the MCP server and UI resource</h2><a class="anchor-link" href="#5-create-the-mcp-server-and-ui-resource"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <ol> <li>Create your main worker at <code dir="auto">src/index.ts</code>:</li> </ol> <div class="expressive-code"><figure class="frame has-title not-content"><figcaption class="header"><span class="title">TypeScript</span></figcaption><pre data-language="ts"><code><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">createMcpHandler</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"agents/mcp"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">routeAgentRequest</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"agents"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">McpServer</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"@modelcontextprotocol/sdk/server/mcp.js"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">env</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"cloudflare:workers"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">getWidgetHtml</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">async</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">host</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EE9080;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080"> </span></span><span style="--0:#EE9080;--1:#8F1500">let</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">html</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">await</span><span style="--0:#EE9080;--1:#32008F"> (</span><span style="--0:#EE9080;--1:#8F1500">await</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">env</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">ASSETS</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">fetch</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#FDDA68;--1:#A84E00">"http://localhost/"</span><span style="--0:#EE9080;--1:#32008F">))</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">text</span><span style="--0:#EE9080;--1:#32008F">()</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#D5D7D8;--1:#8F1500">html</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">html</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">replace</span><span style="--0:#EE9080;--1:#32008F">(</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"<!--RUNTIME_CONFIG-->"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00"><script>window.HOST = </span><span style="--0:#89DDFF;--1:#446E7F">\</span><span style="--0:#89DDFF;--1:#007474">${</span><span style="--0:#D5D7D8;--1:#8F1500">host</span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#89DDFF;--1:#446E7F">\</span><span style="--0:#FDDA68;--1:#A84E00">;</script></span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080"> </span></span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">html</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">function</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">createServer</span><span style="--0:#89DDFF;--1:#007474">()</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">server</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">new</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">McpServer</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EE9080;--1:#32008F"> name</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"Chess"</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> version</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"v1.0.0"</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</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:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic">// Register a UI resource that ChatGPT can render</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">server</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">registerResource</span><span style="--0:#EEFFFF;--1:#62676A">(</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"chess"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"ui://widget/index.html"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">{},</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">async</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">_uri</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">extra</span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">contents</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> [</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">uri</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"ui://widget/index.html"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">mimeType</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"text/html+skybridge"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">text</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">await</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">getWidgetHtml</span><span style="--0:#EEFFFF;--1:#62676A">(</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">extra</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">requestInfo</span><span style="--0:#89DDFF;--1:#007474">?.</span><span style="--0:#EEFFFF;--1:#00268F">headers</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">host</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">as</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">]</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</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:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic">// Register a tool that ChatGPT can call to render the UI</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">server</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">registerTool</span><span style="--0:#EEFFFF;--1:#62676A">(</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"playChess"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">title</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"Renders a chess game menu, ready to start or join a game."</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">annotations</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> readOnlyHint</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">true</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">_meta</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"openai/outputTemplate"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"ui://widget/index.html"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"openai/toolInvocation/invoking"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"Opening chess widget"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"openai/toolInvocation/invoked"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"Chess widget opened"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">async</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">_</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">_extra</span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">content</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> [</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> type</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"text"</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> text</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"Successfully rendered chess game menu"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">]</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</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:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">server</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">export</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">default</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">async</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">fetch</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">req</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">Request</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">env</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">Env</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">ctx</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">ExecutionContext</span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">url</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">new</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">URL</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#EEFFFF;--1:#00268F">req</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">url</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#EEFFFF;--1:#00268F">url</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">pathname</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">startsWith</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#FDDA68;--1:#A84E00">"/mcp"</span><span style="--0:#EEFFFF;--1:#62676A">)) </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic">// Create a new server instance per request</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">server</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">createServer</span><span style="--0:#EE9080;--1:#32008F">()</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">createMcpHandler</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#D5D7D8;--1:#8F1500">server</span><span style="--0:#EEFFFF;--1:#62676A">)(</span><span style="--0:#D5D7D8;--1:#8F1500">req</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">env</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">ctx</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</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:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> (</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#EE9080;--1:#8F1500">await</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">routeAgentRequest</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#D5D7D8;--1:#8F1500">req</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">env</span><span style="--0:#EEFFFF;--1:#62676A">)) </span><span style="--0:#EE9080;--1:#8F1500">??</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">Response</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#FDDA68;--1:#A84E00">"Not found"</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> status</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">404</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EEFFFF;--1:#62676A">)</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">satisfies</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">ExportedHandler</span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#57C78F;--1:#00783C">Env</span><span style="--0:#89DDFF;--1:#007474">>;</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">export</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">ChessGame</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">from</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"./chess"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="import { createMcpHandler } from "agents/mcp";import { routeAgentRequest } from "agents";import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";import { env } from "cloudflare:workers";const getWidgetHtml = async (host: string) => { let html = await (await env.ASSETS.fetch("http://localhost/")).text(); html = html.replace( "<!--RUNTIME_CONFIG-->", `<script>window.HOST = \`${host}\`;</script>`, ); return html;};function createServer() { const server = new McpServer({ name: "Chess", version: "v1.0.0" }); // Register a UI resource that ChatGPT can render server.registerResource( "chess", "ui://widget/index.html", {}, async (_uri, extra) => { return { contents: [ { uri: "ui://widget/index.html", mimeType: "text/html+skybridge", text: await getWidgetHtml( extra.requestInfo?.headers.host as string, ), }, ], }; }, ); // Register a tool that ChatGPT can call to render the UI server.registerTool( "playChess", { title: "Renders a chess game menu, ready to start or join a game.", annotations: { readOnlyHint: true }, _meta: { "openai/outputTemplate": "ui://widget/index.html", "openai/toolInvocation/invoking": "Opening chess widget", "openai/toolInvocation/invoked": "Chess widget opened", }, }, async (_, _extra) => { return { content: [ { type: "text", text: "Successfully rendered chess game menu" }, ], }; }, ); return server;}export default { async fetch(req: Request, env: Env, ctx: ExecutionContext) { const url = new URL(req.url); if (url.pathname.startsWith("/mcp")) { // Create a new server instance per request const server = createServer(); return createMcpHandler(server)(req, env, ctx); } return ( (await routeAgentRequest(req, env)) ?? new Response("Not found", { status: 404 }) ); },} satisfies ExportedHandler<Env>;export { ChessGame } from "./chess";"><div></div></button></div><div class="explain"><button class="explain-button" type="button" data-explain-code="" aria-label="Explain Code"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"></path><path d="M20 3v4"></path><path d="M22 5h-4"></path><path d="M4 17v2"></path><path d="M5 18H3"></path></svg></button></div></figure></div> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="6-build-the-react-ui">6. Build the React UI</h2><a class="anchor-link" href="#6-build-the-react-ui"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <ol> <li>Create the HTML entry point at <code dir="auto">index.html</code>:</li> </ol> <div class="expressive-code"><figure class="frame not-content"><figcaption class="header"></figcaption><pre data-language="html"><code><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474"><!</span><span style="--0:#F38B90;--1:#A54E53">doctype</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#FFCB6B;--0fs:italic;--1:#7E6435;--1fs:italic">html</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#F38B90;--1:#A54E53">html</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#F38B90;--1:#A54E53">head</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic"><!--RUNTIME_CONFIG--></span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474"></</span><span style="--0:#F38B90;--1:#A54E53">head</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#F38B90;--1:#A54E53">body</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#F38B90;--1:#A54E53">div</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#FFCB6B;--0fs:italic;--1:#7E6435;--1fs:italic">id</span><span style="--0:#89DDFF;--1:#007474">=</span><span style="--0:#FDDA68;--1:#A84E00">"root"</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#FFCB6B;--0fs:italic;--1:#7E6435;--1fs:italic">style</span><span style="--0:#89DDFF;--1:#007474">=</span><span style="--0:#FDDA68;--1:#A84E00">"font-family: verdana"</span><span style="--0:#89DDFF;--1:#007474">></</span><span style="--0:#F38B90;--1:#A54E53">div</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#F38B90;--1:#A54E53">script</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#FFCB6B;--0fs:italic;--1:#7E6435;--1fs:italic">type</span><span style="--0:#89DDFF;--1:#007474">=</span><span style="--0:#FDDA68;--1:#A84E00">"module"</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#FFCB6B;--0fs:italic;--1:#7E6435;--1fs:italic">src</span><span style="--0:#89DDFF;--1:#007474">=</span><span style="--0:#FDDA68;--1:#A84E00">"/src/app.tsx"</span><span style="--0:#89DDFF;--1:#007474">></</span><span style="--0:#F38B90;--1:#A54E53">script</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474"></</span><span style="--0:#F38B90;--1:#A54E53">body</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474"></</span><span style="--0:#F38B90;--1:#A54E53">html</span><span style="--0:#89DDFF;--1:#007474">></span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="<!doctype html><html> <head> <!--RUNTIME_CONFIG--> </head> <body> <div id="root" style="font-family: verdana"></div> <script type="module" src="/src/app.tsx"></script> </body></html>"><div></div></button></div><div class="explain"><button class="explain-button" type="button" data-explain-code="" aria-label="Explain Code"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"></path><path d="M20 3v4"></path><path d="M22 5h-4"></path><path d="M4 17v2"></path><path d="M5 18H3"></path></svg></button></div></figure></div> <ol start="2"> <li>Create the React app at <code dir="auto">src/app.tsx</code>:</li> </ol> <div class="expressive-code"><figure class="frame not-content" style="--lnWidth:3ch"><figcaption class="header"></figcaption><pre data-language="tsx"><code><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">useEffect</span></span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">useRef</span></span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">useState</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"react"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">useAgent</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"agents/react"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">createRoot</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"react-dom/client"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">Chess</span></span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--1:#8F1500"><span style="--0:#EE9080"> type </span><span style="--0:#D5D7D8">Square</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"chess.js"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">Chessboard</span></span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--1:#8F1500"><span style="--0:#EE9080"> type </span><span style="--0:#D5D7D8">PieceDropHandlerArgs</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"react-chessboard"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import type </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">State</span><span style="--0:#EE9080"> as </span><span style="--0:#D5D7D8">ServerState</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"./chess"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">function</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">usePlayerId</span><span style="--0:#89DDFF;--1:#007474">()</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">[</span><span style="--0:#EEFFFF;--1:#00268F">pid</span><span style="--0:#89DDFF;--1:#007474">]</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">useState</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">()</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080"> </span></span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">existing</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">localStorage</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">getItem</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#FDDA68;--1:#A84E00">"playerId"</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080"> </span></span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EE9080;--1:#32008F"> (</span><span style="--0:#D5D7D8;--1:#8F1500">existing</span><span style="--0:#EE9080;--1:#32008F">) </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">existing</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080"> </span></span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">id</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">crypto</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">randomUUID</span><span style="--0:#EE9080;--1:#32008F">()</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EEFFFF;--1:#00268F">localStorage</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">setItem</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#FDDA68;--1:#A84E00">"playerId"</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">id</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080"> </span></span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">id</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">pid</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">function</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">App</span><span style="--0:#89DDFF;--1:#007474">()</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">playerId</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">usePlayerId</span><span style="--0:#EE9080;--1:#32008F">()</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">[</span><span style="--0:#EEFFFF;--1:#00268F">gameId</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">setGameId</span><span style="--0:#89DDFF;--1:#007474">]</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">useState</span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">|</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">null</span><span style="--0:#89DDFF;--1:#007474">></span><span style="--0:#EE9080;--1:#32008F">(null)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">[</span><span style="--0:#EEFFFF;--1:#00268F">gameIdInput</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">setGameIdInput</span><span style="--0:#89DDFF;--1:#007474">]</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">useState</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#FDDA68;--1:#A84E00">""</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">[</span><span style="--0:#EEFFFF;--1:#00268F">menuError</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">setMenuError</span><span style="--0:#89DDFF;--1:#007474">]</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">useState</span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">|</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">null</span><span style="--0:#89DDFF;--1:#007474">></span><span style="--0:#EE9080;--1:#32008F">(null)</span><span style="--0:#89DDFF;--1:#007474">;</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:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">gameRef</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">useRef</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#EE9080;--1:#8F1500">new</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">Chess</span><span style="--0:#EE9080;--1:#32008F">())</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">[</span><span style="--0:#EEFFFF;--1:#00268F">fen</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">setFen</span><span style="--0:#89DDFF;--1:#007474">]</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">useState</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#EEFFFF;--1:#00268F">gameRef</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">current</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">fen</span><span style="--0:#EE9080;--1:#32008F">())</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">[</span><span style="--0:#EEFFFF;--1:#00268F">myColor</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">setMyColor</span><span style="--0:#89DDFF;--1:#007474">]</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">useState</span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#FDDA68;--1:#A84E00">"w"</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">|</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"b"</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">|</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"spectator"</span><span style="--0:#89DDFF;--1:#007474">></span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#FDDA68;--1:#A84E00">"spectator"</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">[</span><span style="--0:#EEFFFF;--1:#00268F">pending</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">setPending</span><span style="--0:#89DDFF;--1:#007474">]</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">useState</span><span style="--0:#EE9080;--1:#32008F">(false)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">[</span><span style="--0:#EEFFFF;--1:#00268F">serverState</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">setServerState</span><span style="--0:#89DDFF;--1:#007474">]</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">useState</span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#57C78F;--1:#00783C">ServerState</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">|</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">null</span><span style="--0:#89DDFF;--1:#007474">></span><span style="--0:#EE9080;--1:#32008F">(null)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">[</span><span style="--0:#EEFFFF;--1:#00268F">joined</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">setJoined</span><span style="--0:#89DDFF;--1:#007474">]</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">useState</span><span style="--0:#EE9080;--1:#32008F">(false)</span><span style="--0:#89DDFF;--1:#007474">;</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:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">host</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">window</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">HOST</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">??</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"http://localhost:5173/"</span><span style="--0:#89DDFF;--1:#007474">;</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:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">stub</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">useAgent</span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#57C78F;--1:#00783C">ServerState</span><span style="--0:#89DDFF;--1:#007474">></span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#D5D7D8;--1:#8F1500">host</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">name</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">gameId</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">??</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"__lobby__"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">agent</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"chess"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">onStateUpdate</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">s</span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080"> </span></span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EE9080;--1:#32008F"> (</span><span style="--1:#8F1500"><span style="--0:#EE9080">!</span><span style="--0:#D5D7D8">gameId</span></span><span style="--0:#EE9080;--1:#32008F">) </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EEFFFF;--1:#00268F">gameRef</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">current</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">load</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#EEFFFF;--1:#00268F">s</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">board</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">setFen</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#EEFFFF;--1:#00268F">s</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">board</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">setServerState</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#D5D7D8;--1:#8F1500">s</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</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:#57C78F;--1:#00783C">useEffect</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#89DDFF;--1:#007474">()</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--1:#8F1500"><span style="--0:#EE9080">!</span><span style="--0:#D5D7D8">gameId</span></span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">||</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">joined</span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#89DDFF;--1:#007474">;</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:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#EE9080;--1:#8F1500">async</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">()</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">try</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">res</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">await</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">stub</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">join</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">playerId</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> preferred</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"any"</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#EE9080;--1:#8F1500">!</span><span style="--0:#EEFFFF;--1:#00268F">res</span><span style="--0:#89DDFF;--1:#007474">?.</span><span style="--0:#EEFFFF;--1:#00268F">ok</span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#89DDFF;--1:#007474">;</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:#57C78F;--1:#00783C">setMyColor</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#EEFFFF;--1:#00268F">res</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">role</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">gameRef</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">current</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">load</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#EEFFFF;--1:#00268F">res</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">board</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">setFen</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#EEFFFF;--1:#00268F">res</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">board</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">setServerState</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#EEFFFF;--1:#00268F">res</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">setJoined</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#EE9080;--1:#32008F">true</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">catch</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#D5D7D8;--1:#8F1500">error</span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">console</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">error</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#FDDA68;--1:#A84E00">"Failed to join game"</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">error</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EEFFFF;--1:#62676A">)()</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span><span style="--0:#EEFFFF;--1:#62676A"> [</span><span style="--0:#D5D7D8;--1:#8F1500">playerId</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">gameId</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">stub</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">joined</span><span style="--0:#EEFFFF;--1:#62676A">])</span><span style="--0:#89DDFF;--1:#007474">;</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:#EE9080;--1:#8F1500">async</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">function</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">handleStartNewGame</span><span style="--0:#89DDFF;--1:#007474">()</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">newId</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">crypto</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">randomUUID</span><span style="--0:#EE9080;--1:#32008F">()</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">setGameId</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#D5D7D8;--1:#8F1500">newId</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">setGameIdInput</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#D5D7D8;--1:#8F1500">newId</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">setMenuError</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#EE9080;--1:#32008F">null</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">setJoined</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#EE9080;--1:#32008F">false</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</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:#EE9080;--1:#8F1500">async</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">function</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">handleJoinGame</span><span style="--0:#89DDFF;--1:#007474">()</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">trimmed</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">gameIdInput</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">trim</span><span style="--0:#EE9080;--1:#32008F">()</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--1:#8F1500"><span style="--0:#EE9080">!</span><span style="--0:#D5D7D8">trimmed</span></span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">setMenuError</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#FDDA68;--1:#A84E00">"Enter a game ID to join."</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">setGameId</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#D5D7D8;--1:#8F1500">trimmed</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">setMenuError</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#EE9080;--1:#32008F">null</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">setJoined</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#EE9080;--1:#32008F">false</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</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:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">handleHelpClick</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">()</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EEFFFF;--1:#00268F">window</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">openai</span><span style="--0:#89DDFF;--1:#007474">?.</span><span style="--0:#57C78F;--1:#00783C">sendFollowUpMessage</span><span style="--0:#89DDFF;--1:#007474">?.</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">prompt</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">Help me with my chess game. I am playing as </span><span style="--0:#89DDFF;--1:#007474">${</span><span style="--0:#D5D7D8;--1:#8F1500">myColor</span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#FDDA68;--1:#A84E00"> and the board is: </span><span style="--0:#89DDFF;--1:#007474">${</span><span style="--0:#D5D7D8;--1:#8F1500">fen</span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#FDDA68;--1:#A84E00">. Please only offer written advice.</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">};</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:#EE9080;--1:#8F1500">function</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">onPieceDrop</span><span style="--0:#89DDFF;--1:#007474">({</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">sourceSquare</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">targetSquare</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">PieceDropHandlerArgs</span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--1:#8F1500"><span style="--0:#EE9080">!</span><span style="--0:#D5D7D8">gameId</span></span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">||</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--1:#8F1500"><span style="--0:#EE9080">!</span><span style="--0:#D5D7D8">sourceSquare</span></span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">||</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--1:#8F1500"><span style="--0:#EE9080">!</span><span style="--0:#D5D7D8">targetSquare</span></span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">||</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">pending</span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">false</span><span style="--0:#89DDFF;--1:#007474">;</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:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">gameRef</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">current</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#D5D7D8;--1:#8F1500">myColor</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">===</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"spectator"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">||</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">turn</span><span style="--0:#EEFFFF;--1:#62676A">() </span><span style="--0:#EE9080;--1:#8F1500">!==</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">myColor</span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">false</span><span style="--0:#89DDFF;--1:#007474">;</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:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">piece</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">get</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#D5D7D8;--1:#8F1500">sourceSquare</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">as</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">Square</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--1:#8F1500"><span style="--0:#EE9080">!</span><span style="--0:#D5D7D8">piece</span></span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">||</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EEFFFF;--1:#00268F">piece</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">color</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">!==</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">myColor</span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">false</span><span style="--0:#89DDFF;--1:#007474">;</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:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">prevFen</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">fen</span><span style="--0:#EE9080;--1:#32008F">()</span><span style="--0:#89DDFF;--1:#007474">;</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:#EE9080;--1:#8F1500">try</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">local</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">move</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">from</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">sourceSquare</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">to</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">targetSquare</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">promotion</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"q"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--1:#8F1500"><span style="--0:#EE9080">!</span><span style="--0:#D5D7D8">local</span></span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">false</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">catch</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">false</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</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:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">nextFen</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">fen</span><span style="--0:#EE9080;--1:#32008F">()</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">setFen</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#D5D7D8;--1:#8F1500">nextFen</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">setPending</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#EE9080;--1:#32008F">true</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</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:#D5D7D8;--1:#8F1500">stub</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">move</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> from</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">sourceSquare</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> to</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">targetSquare</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> promotion</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"q"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">},</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">prevFen</span><span style="--0:#EEFFFF;--1:#62676A">)</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">then</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">r</span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#EE9080;--1:#8F1500">!</span><span style="--0:#EEFFFF;--1:#00268F">r</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">ok</span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">load</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#EEFFFF;--1:#00268F">r</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">fen</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">setFen</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#EEFFFF;--1:#00268F">r</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">fen</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EEFFFF;--1:#62676A">)</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">finally</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#89DDFF;--1:#007474">()</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">setPending</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#EE9080;--1:#32008F">false</span><span style="--0:#EEFFFF;--1:#62676A">))</span><span style="--0:#89DDFF;--1:#007474">;</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:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">true</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</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:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> (</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#F38B90;--1:#A54E53">div</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#C895EA;--1:#7C5B92">style</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{{ padding: </span><span style="--0:#FDDA68;--1:#A84E00">"20px"</span><span style="--0:#89DDFF;--1:#007474">, background: </span><span style="--0:#FDDA68;--1:#A84E00">"#f8fafc"</span><span style="--0:#89DDFF;--1:#007474">, minHeight: </span><span style="--0:#FDDA68;--1:#A84E00">"100vh"</span><span style="--0:#89DDFF;--1:#007474"> }}></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080">!</span><span style="--0:#D5D7D8">gameId</span></span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#EE9080;--1:#8F1500">?</span><span style="--0:#89DDFF;--1:#007474"> (</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#F38B90;--1:#A54E53">div</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#C895EA;--1:#7C5B92">style</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">maxWidth: </span><span style="--0:#FDDA68;--1:#A84E00">"420px"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">margin: </span><span style="--0:#FDDA68;--1:#A84E00">"0 auto"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">background: </span><span style="--0:#FDDA68;--1:#A84E00">"#fff"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">borderRadius: </span><span style="--0:#FDDA68;--1:#A84E00">"16px"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">padding: </span><span style="--0:#FDDA68;--1:#A84E00">"24px"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">}}</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#F38B90;--1:#A54E53">h1</span><span style="--0:#89DDFF;--1:#007474">>Ready to play?</</span><span style="--0:#F38B90;--1:#A54E53">h1</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#F38B90;--1:#A54E53">p</span><span style="--0:#89DDFF;--1:#007474">>Start a new match or join an existing game.</</span><span style="--0:#F38B90;--1:#A54E53">p</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#F38B90;--1:#A54E53">button</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#C895EA;--1:#7C5B92">onClick</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#D5D7D8;--1:#8F1500">handleStartNewGame</span><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#C895EA;--1:#7C5B92">style</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">padding: </span><span style="--0:#FDDA68;--1:#A84E00">"12px"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">background: </span><span style="--0:#FDDA68;--1:#A84E00">"#2563eb"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">color: </span><span style="--0:#FDDA68;--1:#A84E00">"#fff"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">border: </span><span style="--0:#FDDA68;--1:#A84E00">"none"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">borderRadius: </span><span style="--0:#FDDA68;--1:#A84E00">"8px"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">cursor: </span><span style="--0:#FDDA68;--1:#A84E00">"pointer"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">width: </span><span style="--0:#FDDA68;--1:#A84E00">"100%"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">}}</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">Start a new game</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"></</span><span style="--0:#F38B90;--1:#A54E53">button</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#F38B90;--1:#A54E53">div</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#C895EA;--1:#7C5B92">style</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{{ marginTop: </span><span style="--0:#FDDA68;--1:#A84E00">"16px"</span><span style="--0:#89DDFF;--1:#007474"> }}></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#F38B90;--1:#A54E53">input</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#C895EA;--1:#7C5B92">placeholder</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#FDDA68;--1:#A84E00">"Paste a game ID"</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#C895EA;--1:#7C5B92">value</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#D5D7D8;--1:#8F1500">gameIdInput</span><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#C895EA;--1:#7C5B92">onChange</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{(</span><span style="--0:#B59EE1;--1:#7C008F">e</span><span style="--0:#89DDFF;--1:#007474">) </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">setGameIdInput</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#EEFFFF;--1:#00268F">e</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">target</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">value</span><span style="--0:#89DDFF;--1:#007474">)}</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#C895EA;--1:#7C5B92">style</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">width: </span><span style="--0:#FDDA68;--1:#A84E00">"100%"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">padding: </span><span style="--0:#FDDA68;--1:#A84E00">"10px"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">borderRadius: </span><span style="--0:#FDDA68;--1:#A84E00">"8px"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">border: </span><span style="--0:#FDDA68;--1:#A84E00">"1px solid #ccc"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">}}</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">/></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#F38B90;--1:#A54E53">button</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#C895EA;--1:#7C5B92">onClick</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#D5D7D8;--1:#8F1500">handleJoinGame</span><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#C895EA;--1:#7C5B92">style</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">marginTop: </span><span style="--0:#FDDA68;--1:#A84E00">"8px"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">padding: </span><span style="--0:#FDDA68;--1:#A84E00">"10px"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">background: </span><span style="--0:#FDDA68;--1:#A84E00">"#0f172a"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">color: </span><span style="--0:#FDDA68;--1:#A84E00">"#fff"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">border: </span><span style="--0:#FDDA68;--1:#A84E00">"none"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">borderRadius: </span><span style="--0:#FDDA68;--1:#A84E00">"8px"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">cursor: </span><span style="--0:#FDDA68;--1:#A84E00">"pointer"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">width: </span><span style="--0:#FDDA68;--1:#A84E00">"100%"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">}}</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">Join</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"></</span><span style="--0:#F38B90;--1:#A54E53">button</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#D5D7D8;--1:#8F1500">menuError</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#EE9080;--1:#8F1500">&&</span><span style="--0:#89DDFF;--1:#007474"> (</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#F38B90;--1:#A54E53">p</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#C895EA;--1:#7C5B92">style</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{{ color: </span><span style="--0:#FDDA68;--1:#A84E00">"red"</span><span style="--0:#89DDFF;--1:#007474">, fontSize: </span><span style="--0:#FDDA68;--1:#A84E00">"0.85rem"</span><span style="--0:#89DDFF;--1:#007474"> }}>{</span><span style="--0:#D5D7D8;--1:#8F1500">menuError</span><span style="--0:#89DDFF;--1:#007474">}</</span><span style="--0:#F38B90;--1:#A54E53">p</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">)}</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"></</span><span style="--0:#F38B90;--1:#A54E53">div</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"></</span><span style="--0:#F38B90;--1:#A54E53">div</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">) </span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#89DDFF;--1:#007474"> (</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#F38B90;--1:#A54E53">div</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#C895EA;--1:#7C5B92">style</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{{ maxWidth: </span><span style="--0:#FDDA68;--1:#A84E00">"600px"</span><span style="--0:#89DDFF;--1:#007474">, margin: </span><span style="--0:#FDDA68;--1:#A84E00">"0 auto"</span><span style="--0:#89DDFF;--1:#007474"> }}></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#F38B90;--1:#A54E53">div</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#C895EA;--1:#7C5B92">style</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">background: </span><span style="--0:#FDDA68;--1:#A84E00">"#fff"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">padding: </span><span style="--0:#FDDA68;--1:#A84E00">"16px"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">borderRadius: </span><span style="--0:#FDDA68;--1:#A84E00">"16px"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">marginBottom: </span><span style="--0:#FDDA68;--1:#A84E00">"16px"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">}}</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#F38B90;--1:#A54E53">h2</span><span style="--0:#89DDFF;--1:#007474">>Game {</span><span style="--0:#D5D7D8;--1:#8F1500">gameId</span><span style="--0:#89DDFF;--1:#007474">}</</span><span style="--0:#F38B90;--1:#A54E53">h2</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#F38B90;--1:#A54E53">p</span><span style="--0:#89DDFF;--1:#007474">>Status: {</span><span style="--0:#EEFFFF;--1:#00268F">serverState</span><span style="--0:#89DDFF;--1:#007474">?.</span><span style="--0:#EEFFFF;--1:#00268F">status</span><span style="--0:#89DDFF;--1:#007474">}</</span><span style="--0:#F38B90;--1:#A54E53">p</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#F38B90;--1:#A54E53">button</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#C895EA;--1:#7C5B92">onClick</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#D5D7D8;--1:#8F1500">handleHelpClick</span><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#C895EA;--1:#7C5B92">style</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">padding: </span><span style="--0:#FDDA68;--1:#A84E00">"10px"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">background: </span><span style="--0:#FDDA68;--1:#A84E00">"#2563eb"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">color: </span><span style="--0:#FDDA68;--1:#A84E00">"#fff"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">border: </span><span style="--0:#FDDA68;--1:#A84E00">"none"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">borderRadius: </span><span style="--0:#FDDA68;--1:#A84E00">"8px"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">cursor: </span><span style="--0:#FDDA68;--1:#A84E00">"pointer"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">}}</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">Ask for help</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"></</span><span style="--0:#F38B90;--1:#A54E53">button</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"></</span><span style="--0:#F38B90;--1:#A54E53">div</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#F38B90;--1:#A54E53">div</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#C895EA;--1:#7C5B92">style</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">background: </span><span style="--0:#FDDA68;--1:#A84E00">"#fff"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">padding: </span><span style="--0:#FDDA68;--1:#A84E00">"16px"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">borderRadius: </span><span style="--0:#FDDA68;--1:#A84E00">"16px"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">}}</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#57C78F;--1:#00783C">Chessboard</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#C895EA;--1:#7C5B92">position</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#D5D7D8;--1:#8F1500">fen</span><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#C895EA;--1:#7C5B92">onPieceDrop</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#D5D7D8;--1:#8F1500">onPieceDrop</span><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#C895EA;--1:#7C5B92">boardOrientation</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#D5D7D8;--1:#8F1500">myColor</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#EE9080;--1:#8F1500">===</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#FDDA68;--1:#A84E00">"b"</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#EE9080;--1:#8F1500">?</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#FDDA68;--1:#A84E00">"black"</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#FDDA68;--1:#A84E00">"white"</span><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">/></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"></</span><span style="--0:#F38B90;--1:#A54E53">div</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"></</span><span style="--0:#F38B90;--1:#A54E53">div</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">)}</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"></</span><span style="--0:#F38B90;--1:#A54E53">div</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">root</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">createRoot</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#EEFFFF;--1:#00268F">document</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">getElementById</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#FDDA68;--1:#A84E00">"root"</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#EE9080;--1:#8F1500">!</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EEFFFF;--1:#00268F">root</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">render</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#57C78F;--1:#00783C">App</span><span style="--0:#89DDFF;--1:#007474"> /></span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="import { useEffect, useRef, useState } from "react";import { useAgent } from "agents/react";import { createRoot } from "react-dom/client";import { Chess, type Square } from "chess.js";import { Chessboard, type PieceDropHandlerArgs } from "react-chessboard";import type { State as ServerState } from "./chess";function usePlayerId() { const [pid] = useState(() => { const existing = localStorage.getItem("playerId"); if (existing) return existing; const id = crypto.randomUUID(); localStorage.setItem("playerId", id); return id; }); return pid;}function App() { const playerId = usePlayerId(); const [gameId, setGameId] = useState<string | null>(null); const [gameIdInput, setGameIdInput] = useState(""); const [menuError, setMenuError] = useState<string | null>(null); const gameRef = useRef(new Chess()); const [fen, setFen] = useState(gameRef.current.fen()); const [myColor, setMyColor] = useState<"w" | "b" | "spectator">("spectator"); const [pending, setPending] = useState(false); const [serverState, setServerState] = useState<ServerState | null>(null); const [joined, setJoined] = useState(false); const host = window.HOST ?? "http://localhost:5173/"; const { stub } = useAgent<ServerState>({ host, name: gameId ?? "__lobby__", agent: "chess", onStateUpdate: (s) => { if (!gameId) return; gameRef.current.load(s.board); setFen(s.board); setServerState(s); }, }); useEffect(() => { if (!gameId || joined) return; (async () => { try { const res = await stub.join({ playerId, preferred: "any" }); if (!res?.ok) return; setMyColor(res.role); gameRef.current.load(res.state.board); setFen(res.state.board); setServerState(res.state); setJoined(true); } catch (error) { console.error("Failed to join game", error); } })(); }, [playerId, gameId, stub, joined]); async function handleStartNewGame() { const newId = crypto.randomUUID(); setGameId(newId); setGameIdInput(newId); setMenuError(null); setJoined(false); } async function handleJoinGame() { const trimmed = gameIdInput.trim(); if (!trimmed) { setMenuError("Enter a game ID to join."); return; } setGameId(trimmed); setMenuError(null); setJoined(false); } const handleHelpClick = () => { window.openai?.sendFollowUpMessage?.({ prompt: `Help me with my chess game. I am playing as ${myColor} and the board is: ${fen}. Please only offer written advice.`, }); }; function onPieceDrop({ sourceSquare, targetSquare }: PieceDropHandlerArgs) { if (!gameId || !sourceSquare || !targetSquare || pending) return false; const game = gameRef.current; if (myColor === "spectator" || game.turn() !== myColor) return false; const piece = game.get(sourceSquare as Square); if (!piece || piece.color !== myColor) return false; const prevFen = game.fen(); try { const local = game.move({ from: sourceSquare, to: targetSquare, promotion: "q", }); if (!local) return false; } catch { return false; } const nextFen = game.fen(); setFen(nextFen); setPending(true); stub .move({ from: sourceSquare, to: targetSquare, promotion: "q" }, prevFen) .then((r) => { if (!r.ok) { game.load(r.fen); setFen(r.fen); } }) .finally(() => setPending(false)); return true; } return ( <div style={{ padding: "20px", background: "#f8fafc", minHeight: "100vh" }}> {!gameId ? ( <div style={{ maxWidth: "420px", margin: "0 auto", background: "#fff", borderRadius: "16px", padding: "24px", }} > <h1>Ready to play?</h1> <p>Start a new match or join an existing game.</p> <button onClick={handleStartNewGame} style={{ padding: "12px", background: "#2563eb", color: "#fff", border: "none", borderRadius: "8px", cursor: "pointer", width: "100%", }} > Start a new game </button> <div style={{ marginTop: "16px" }}> <input placeholder="Paste a game ID" value={gameIdInput} onChange={(e) => setGameIdInput(e.target.value)} style={{ width: "100%", padding: "10px", borderRadius: "8px", border: "1px solid #ccc", }} /> <button onClick={handleJoinGame} style={{ marginTop: "8px", padding: "10px", background: "#0f172a", color: "#fff", border: "none", borderRadius: "8px", cursor: "pointer", width: "100%", }} > Join </button> {menuError && ( <p style={{ color: "red", fontSize: "0.85rem" }}>{menuError}</p> )} </div> </div> ) : ( <div style={{ maxWidth: "600px", margin: "0 auto" }}> <div style={{ background: "#fff", padding: "16px", borderRadius: "16px", marginBottom: "16px", }} > <h2>Game {gameId}</h2> <p>Status: {serverState?.status}</p> <button onClick={handleHelpClick} style={{ padding: "10px", background: "#2563eb", color: "#fff", border: "none", borderRadius: "8px", cursor: "pointer", }} > Ask for help </button> </div> <div style={{ background: "#fff", padding: "16px", borderRadius: "16px", }} > <Chessboard position={fen} onPieceDrop={onPieceDrop} boardOrientation={myColor === "b" ? "black" : "white"} /> </div> </div> )} </div> );}const root = createRoot(document.getElementById("root")!);root.render(<App />);"><div></div></button></div><div class="explain"><button class="explain-button" type="button" data-explain-code="" aria-label="Explain Code"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"></path><path d="M20 3v4"></path><path d="M22 5h-4"></path><path d="M4 17v2"></path><path d="M5 18H3"></path></svg></button></div></figure></div> <aside aria-label="Note" class="starlight-aside starlight-aside--note"><p class="starlight-aside__title" aria-hidden="true"><svg viewBox="0 0 24 24" width="16" height="16" fill="currentColor" class="starlight-aside__icon"><path d="M12 11C11.7348 11 11.4804 11.1054 11.2929 11.2929C11.1054 11.4804 11 11.7348 11 12V16C11 16.2652 11.1054 16.5196 11.2929 16.7071C11.4804 16.8946 11.7348 17 12 17C12.2652 17 12.5196 16.8946 12.7071 16.7071C12.8946 16.5196 13 16.2652 13 16V12C13 11.7348 12.8946 11.4804 12.7071 11.2929C12.5196 11.1054 12.2652 11 12 11ZM12.38 7.08C12.1365 6.97998 11.8635 6.97998 11.62 7.08C11.4973 7.12759 11.3851 7.19896 11.29 7.29C11.2017 7.3872 11.1306 7.49882 11.08 7.62C11.024 7.73868 10.9966 7.86882 11 8C10.9992 8.13161 11.0245 8.26207 11.0742 8.38391C11.124 8.50574 11.1973 8.61656 11.29 8.71C11.3872 8.79833 11.4988 8.86936 11.62 8.92C11.7715 8.98224 11.936 9.00632 12.099 8.99011C12.2619 8.97391 12.4184 8.91792 12.5547 8.82707C12.691 8.73622 12.8029 8.61328 12.8805 8.46907C12.9582 8.32486 12.9992 8.16378 13 8C12.9963 7.73523 12.8927 7.48163 12.71 7.29C12.6149 7.19896 12.5028 7.12759 12.38 7.08ZM12 2C10.0222 2 8.08879 2.58649 6.4443 3.6853C4.79981 4.78412 3.51809 6.3459 2.76121 8.17317C2.00433 10.0004 1.8063 12.0111 2.19215 13.9509C2.578 15.8907 3.53041 17.6725 4.92894 19.0711C6.32746 20.4696 8.10929 21.422 10.0491 21.8079C11.9889 22.1937 13.9996 21.9957 15.8268 21.2388C17.6541 20.4819 19.2159 19.2002 20.3147 17.5557C21.4135 15.9112 22 13.9778 22 12C22 10.6868 21.7413 9.38642 21.2388 8.17317C20.7363 6.95991 19.9997 5.85752 19.0711 4.92893C18.1425 4.00035 17.0401 3.26375 15.8268 2.7612C14.6136 2.25866 13.3132 2 12 2ZM12 20C10.4178 20 8.87104 19.5308 7.55544 18.6518C6.23985 17.7727 5.21447 16.5233 4.60897 15.0615C4.00347 13.5997 3.84504 11.9911 4.15372 10.4393C4.4624 8.88743 5.22433 7.46197 6.34315 6.34315C7.46197 5.22433 8.88743 4.4624 10.4393 4.15372C11.9911 3.84504 13.5997 4.00346 15.0615 4.60896C16.5233 5.21447 17.7727 6.23984 18.6518 7.55544C19.5308 8.87103 20 10.4177 20 12C20 14.1217 19.1572 16.1566 17.6569 17.6569C16.1566 19.1571 14.1217 20 12 20Z"></path></svg>Note</p><div class="starlight-aside__content"><p>This is a simplified version of the UI. For the complete implementation with player slots, better styling, and game state management, check out the <a href="https://github.com/cloudflare/agents/tree/main/openai-sdk/chess-app/src/app.tsx" target="_blank" rel="noopener">full example on GitHub<span class="external-link"> ↗</span></a>.</p></div></aside> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="7-build-and-deploy">7. Build and deploy</h2><a class="anchor-link" href="#7-build-and-deploy"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <ol> <li>Build your React UI:</li> </ol> <div class="expressive-code"><figure class="frame is-terminal not-content"><figcaption class="header"><span class="title"></span><span class="sr-only">Terminal window</span></figcaption><pre data-language="sh"><code><div class="ec-line"><div class="code"><span style="--0:#57C78F;--1:#00783C">npm</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">run</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">build</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="npm run build"><div></div></button></div></figure></div> <p>This compiles your React app into a single HTML file in the <code dir="auto">dist</code> directory.</p> <ol start="2"> <li>Deploy to Cloudflare:</li> </ol> <div class="expressive-code"><figure class="frame is-terminal not-content"><figcaption class="header"><span class="title"></span><span class="sr-only">Terminal window</span></figcaption><pre data-language="sh"><code><div class="ec-line"><div class="code"><span style="--0:#57C78F;--1:#00783C">npx</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">wrangler</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">deploy</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="npx wrangler deploy"><div></div></button></div></figure></div> <p>After deployment, you will see your app URL:</p> <div class="expressive-code"><figure class="frame not-content"><figcaption class="header"></figcaption><pre data-language="plaintext"><code><div class="ec-line"><div class="code"><span style="--0:#eeffff;--1:#62676a">https://my-chess-app.YOUR_SUBDOMAIN.workers.dev</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="https://my-chess-app.YOUR_SUBDOMAIN.workers.dev"><div></div></button></div></figure></div> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="8-connect-to-chatgpt">8. Connect to ChatGPT</h2><a class="anchor-link" href="#8-connect-to-chatgpt"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <p>Now connect your deployed app to ChatGPT:</p> <ol> <li>Open <a href="https://chat.openai.com/" target="_blank" rel="noopener">ChatGPT<span class="external-link"> ↗</span></a>.</li> <li>Go to <strong>Settings</strong> > <strong>Apps & Connectors</strong> > <strong>Create</strong></li> <li>Give your app a <strong>name</strong>, and optionally a <strong>description</strong> and <strong>icon</strong>.</li> <li>Enter your MCP endpoint: <code dir="auto">https://my-chess-app.YOUR_SUBDOMAIN.workers.dev/mcp</code>.</li> <li>Select <strong>"No authentication"</strong>.</li> <li>Select <strong>"Create"</strong>.</li> </ol> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="9-play-chess-in-chatgpt">9. Play chess in ChatGPT</h2><a class="anchor-link" href="#9-play-chess-in-chatgpt"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <p>Try it out:</p> <ol> <li>In your ChatGPT conversation, type: "Let's play chess".</li> <li>ChatGPT will call the <code dir="auto">playChess</code> tool and render your interactive chess widget.</li> <li>Select <strong>"Start a new game"</strong> to create a game.</li> <li>Share the game ID with a friend who can join via their own ChatGPT conversation.</li> <li>Make moves by dragging pieces on the board.</li> <li>Select <strong>"Ask for help"</strong> to get strategic advice from ChatGPT</li> </ol> <aside aria-label="Note" class="starlight-aside starlight-aside--note"><p class="starlight-aside__title" aria-hidden="true"><svg viewBox="0 0 24 24" width="16" height="16" fill="currentColor" class="starlight-aside__icon"><path d="M12 11C11.7348 11 11.4804 11.1054 11.2929 11.2929C11.1054 11.4804 11 11.7348 11 12V16C11 16.2652 11.1054 16.5196 11.2929 16.7071C11.4804 16.8946 11.7348 17 12 17C12.2652 17 12.5196 16.8946 12.7071 16.7071C12.8946 16.5196 13 16.2652 13 16V12C13 11.7348 12.8946 11.4804 12.7071 11.2929C12.5196 11.1054 12.2652 11 12 11ZM12.38 7.08C12.1365 6.97998 11.8635 6.97998 11.62 7.08C11.4973 7.12759 11.3851 7.19896 11.29 7.29C11.2017 7.3872 11.1306 7.49882 11.08 7.62C11.024 7.73868 10.9966 7.86882 11 8C10.9992 8.13161 11.0245 8.26207 11.0742 8.38391C11.124 8.50574 11.1973 8.61656 11.29 8.71C11.3872 8.79833 11.4988 8.86936 11.62 8.92C11.7715 8.98224 11.936 9.00632 12.099 8.99011C12.2619 8.97391 12.4184 8.91792 12.5547 8.82707C12.691 8.73622 12.8029 8.61328 12.8805 8.46907C12.9582 8.32486 12.9992 8.16378 13 8C12.9963 7.73523 12.8927 7.48163 12.71 7.29C12.6149 7.19896 12.5028 7.12759 12.38 7.08ZM12 2C10.0222 2 8.08879 2.58649 6.4443 3.6853C4.79981 4.78412 3.51809 6.3459 2.76121 8.17317C2.00433 10.0004 1.8063 12.0111 2.19215 13.9509C2.578 15.8907 3.53041 17.6725 4.92894 19.0711C6.32746 20.4696 8.10929 21.422 10.0491 21.8079C11.9889 22.1937 13.9996 21.9957 15.8268 21.2388C17.6541 20.4819 19.2159 19.2002 20.3147 17.5557C21.4135 15.9112 22 13.9778 22 12C22 10.6868 21.7413 9.38642 21.2388 8.17317C20.7363 6.95991 19.9997 5.85752 19.0711 4.92893C18.1425 4.00035 17.0401 3.26375 15.8268 2.7612C14.6136 2.25866 13.3132 2 12 2ZM12 20C10.4178 20 8.87104 19.5308 7.55544 18.6518C6.23985 17.7727 5.21447 16.5233 4.60897 15.0615C4.00347 13.5997 3.84504 11.9911 4.15372 10.4393C4.4624 8.88743 5.22433 7.46197 6.34315 6.34315C7.46197 5.22433 8.88743 4.4624 10.4393 4.15372C11.9911 3.84504 13.5997 4.00346 15.0615 4.60896C16.5233 5.21447 17.7727 6.23984 18.6518 7.55544C19.5308 8.87103 20 10.4177 20 12C20 14.1217 19.1572 16.1566 17.6569 17.6569C16.1566 19.1571 14.1217 20 12 20Z"></path></svg>Note</p><div class="starlight-aside__content"><p>You might need to manually select the connector in the prompt box the first time you use it. Select <strong>"+"</strong> > <strong>"More"</strong> > <strong>[App name]</strong>.</p></div></aside> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="key-concepts">Key concepts</h2><a class="anchor-link" href="#key-concepts"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <div tabindex="-1" class="heading-wrapper level-h3"><h3 id="mcp-server">MCP Server</h3><a class="anchor-link" href="#mcp-server"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <p>The Model Context Protocol (MCP) server defines tools and resources that ChatGPT can access. Note that we create a new server instance per request to prevent cross-client response leakage:</p> <div class="expressive-code"><figure class="frame has-title not-content"><figcaption class="header"><span class="title">TypeScript</span></figcaption><pre data-language="ts"><code><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">function</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">createServer</span><span style="--0:#89DDFF;--1:#007474">()</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">server</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">new</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">McpServer</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EE9080;--1:#32008F"> name</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"Chess"</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> version</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"v1.0.0"</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</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:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic">// Register a UI resource that ChatGPT can render</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">server</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">registerResource</span><span style="--0:#EEFFFF;--1:#62676A">(</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"chess"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"ui://widget/index.html"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">{},</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">async</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">_uri</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">extra</span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">contents</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> [</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">uri</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"ui://widget/index.html"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">mimeType</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"text/html+skybridge"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">text</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">await</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">getWidgetHtml</span><span style="--0:#EEFFFF;--1:#62676A">(</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">extra</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">requestInfo</span><span style="--0:#89DDFF;--1:#007474">?.</span><span style="--0:#EEFFFF;--1:#00268F">headers</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">host</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">as</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">]</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</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:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic">// Register a tool that ChatGPT can call to render the UI</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">server</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">registerTool</span><span style="--0:#EEFFFF;--1:#62676A">(</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"playChess"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">title</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"Renders a chess game menu, ready to start or join a game."</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">annotations</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> readOnlyHint</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">true</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">_meta</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"openai/outputTemplate"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"ui://widget/index.html"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"openai/toolInvocation/invoking"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"Opening chess widget"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"openai/toolInvocation/invoked"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"Chess widget opened"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">async</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">_</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">_extra</span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">content</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> [</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> type</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"text"</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> text</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"Successfully rendered chess game menu"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">]</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</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:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">server</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">}</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="function createServer() { const server = new McpServer({ name: "Chess", version: "v1.0.0" }); // Register a UI resource that ChatGPT can render server.registerResource( "chess", "ui://widget/index.html", {}, async (_uri, extra) => { return { contents: [ { uri: "ui://widget/index.html", mimeType: "text/html+skybridge", text: await getWidgetHtml( extra.requestInfo?.headers.host as string, ), }, ], }; }, ); // Register a tool that ChatGPT can call to render the UI server.registerTool( "playChess", { title: "Renders a chess game menu, ready to start or join a game.", annotations: { readOnlyHint: true }, _meta: { "openai/outputTemplate": "ui://widget/index.html", "openai/toolInvocation/invoking": "Opening chess widget", "openai/toolInvocation/invoked": "Chess widget opened", }, }, async (_, _extra) => { return { content: [ { type: "text", text: "Successfully rendered chess game menu" }, ], }; }, ); return server;}"><div></div></button></div><div class="explain"><button class="explain-button" type="button" data-explain-code="" aria-label="Explain Code"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"></path><path d="M20 3v4"></path><path d="M22 5h-4"></path><path d="M4 17v2"></path><path d="M5 18H3"></path></svg></button></div></figure></div> <div tabindex="-1" class="heading-wrapper level-h3"><h3 id="game-engine-with-agents">Game Engine with Agents</h3><a class="anchor-link" href="#game-engine-with-agents"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <p>The <code dir="auto">ChessGame</code> class extends <code dir="auto">Agent</code> to create a stateful game engine:</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:#EE9080;--1:#8F1500">export</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">class</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">ChessGame</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">extends</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">Agent</span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#57C78F;--1:#00783C">Env</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">State</span><span style="--0:#89DDFF;--1:#007474">></span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">initialState</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">State</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">board</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">Chess</span><span style="--0:#EEFFFF;--1:#62676A">()</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">fen</span><span style="--0:#EEFFFF;--1:#62676A">()</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">players</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{},</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">status</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"waiting"</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">};</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:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">Chess</span><span style="--0:#EEFFFF;--1:#62676A">()</span><span style="--0:#89DDFF;--1:#007474">;</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:#EE9080;--1:#8F1500">constructor</span><span style="--0:#89DDFF;--1:#007474">(</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#B59EE1;--1:#7C008F">ctx</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">DurableObjectState</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">public</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">env</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">Env</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">super</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#D5D7D8;--1:#8F1500">ctx</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">env</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">load</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">board</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="export class ChessGame extends Agent<Env, State> { initialState: State = { board: new Chess().fen(), players: {}, status: "waiting" }; game = new Chess(); constructor( ctx: DurableObjectState, public env: Env ) { super(ctx, env); this.game.load(this.state.board); }"><div></div></button></div><div class="explain"><button class="explain-button" type="button" data-explain-code="" aria-label="Explain Code"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"></path><path d="M20 3v4"></path><path d="M22 5h-4"></path><path d="M4 17v2"></path><path d="M5 18H3"></path></svg></button></div></figure></div> <p>Each game gets its own Agent instance, enabling:</p> <ul> <li><strong>Isolated state</strong> per game</li> <li><strong>Real-time synchronization</strong> across players</li> <li><strong>Persistent storage</strong> that survives worker restarts</li> </ul> <div tabindex="-1" class="heading-wrapper level-h3"><h3 id="callable-methods">Callable methods</h3><a class="anchor-link" href="#callable-methods"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <p>Use the <code dir="auto">@callable()</code> decorator to expose methods that clients can invoke:</p> <div class="expressive-code"><figure class="frame has-title not-content"><figcaption class="header"><span class="title">TypeScript</span></figcaption><pre data-language="ts"><code><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">@</span><span style="--0:#57C78F;--1:#00783C">callable</span><span style="--0:#EEFFFF;--1:#62676A">()</span></div></div><div class="ec-line"><div class="code"><span style="--0:#57C78F;--1:#00783C">join</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#D5D7D8;--1:#8F1500">params</span><span style="--0:#EEFFFF;--1:#62676A">: </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> playerId</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">string</span><span style="--0:#EEFFFF;--1:#62676A">; </span><span style="--1:#8F1500"><span style="--0:#D5D7D8">preferred</span><span style="--0:#EE9080">?:</span></span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">Color</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">|</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"any"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">playerId</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">preferred</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"any"</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">params</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">connection</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">getCurrentAgent</span><span style="--0:#EE9080;--1:#32008F">()</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--1:#8F1500"><span style="--0:#EE9080">!</span><span style="--0:#D5D7D8">connection</span></span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#EE9080;--1:#8F1500">throw</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">Error</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#FDDA68;--1:#A84E00">"Not connected"</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</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:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">connection</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">setState</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">playerId</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">s</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#89DDFF;--1:#007474">;</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:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic">// Already seated? Return seat</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">already</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">colorOf</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#D5D7D8;--1:#8F1500">playerId</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#D5D7D8;--1:#8F1500">already</span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> ok</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">true</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> role</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">already</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">as</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">Color</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> state</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">s</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</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:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic">// Choose a seat</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">free</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EE9080;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">Color</span><span style="--0:#EE9080;--1:#007474">[] </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> ([</span><span style="--0:#FDDA68;--1:#A84E00">"w"</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"b"</span><span style="--0:#EE9080;--1:#32008F">] </span><span style="--0:#EE9080;--1:#8F1500">as</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">filter</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">c</span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">!</span><span style="--0:#EEFFFF;--1:#00268F">s</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">players</span><span style="--0:#EE9080;--1:#32008F">[</span><span style="--0:#D5D7D8;--1:#8F1500">c</span><span style="--0:#EE9080;--1:#32008F">])</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#EEFFFF;--1:#00268F">free</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#9D5600">length</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">===</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">0</span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> ok</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">true</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> role</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"spectator"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">as</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> state</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">s</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</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:#EE9080;--1:#8F1500">let</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--1:#8F1500"><span style="--0:#D5D7D8">seat</span><span style="--0:#EE9080">:</span></span><span style="--0:#EE9080;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">Color</span><span style="--0:#EE9080;--1:#007474"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">free</span><span style="--0:#EE9080;--1:#32008F">[</span><span style="--0:#B59EE1;--1:#7C008F">0</span><span style="--0:#EE9080;--1:#32008F">]</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#D5D7D8;--1:#8F1500">preferred</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">===</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"w"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">&&</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EEFFFF;--1:#00268F">free</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">includes</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#FDDA68;--1:#A84E00">"w"</span><span style="--0:#EEFFFF;--1:#62676A">)) </span><span style="--0:#D5D7D8;--1:#8F1500">seat</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"w"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#D5D7D8;--1:#8F1500">preferred</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">===</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"b"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">&&</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EEFFFF;--1:#00268F">free</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">includes</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#FDDA68;--1:#A84E00">"b"</span><span style="--0:#EEFFFF;--1:#62676A">)) </span><span style="--0:#D5D7D8;--1:#8F1500">seat</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"b"</span><span style="--0:#89DDFF;--1:#007474">;</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:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">s</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">players</span><span style="--0:#EEFFFF;--1:#62676A">[</span><span style="--0:#D5D7D8;--1:#8F1500">seat</span><span style="--0:#EEFFFF;--1:#62676A">] </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">playerId</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">s</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">status</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EEFFFF;--1:#00268F">s</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">players</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">w</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">&&</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EEFFFF;--1:#00268F">s</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">players</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">b</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">?</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"active"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"waiting"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">setState</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#D5D7D8;--1:#8F1500">s</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> ok</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">true</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> role</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">seat</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> state</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">s</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">}</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="@callable()join(params: { playerId: string; preferred?: Color | "any" }) { const { playerId, preferred = "any" } = params; const { connection } = getCurrentAgent(); if (!connection) throw new Error("Not connected"); connection.setState({ playerId }); const s = this.state; // Already seated? Return seat const already = this.colorOf(playerId); if (already) { return { ok: true, role: already as Color, state: s }; } // Choose a seat const free: Color[] = (["w", "b"] as const).filter((c) => !s.players[c]); if (free.length === 0) { return { ok: true, role: "spectator" as const, state: s }; } let seat: Color = free[0]; if (preferred === "w" && free.includes("w")) seat = "w"; if (preferred === "b" && free.includes("b")) seat = "b"; s.players[seat] = playerId; s.status = s.players.w && s.players.b ? "active" : "waiting"; this.setState(s); return { ok: true, role: seat, state: s };}"><div></div></button></div><div class="explain"><button class="explain-button" type="button" data-explain-code="" aria-label="Explain Code"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"></path><path d="M20 3v4"></path><path d="M22 5h-4"></path><path d="M4 17v2"></path><path d="M5 18H3"></path></svg></button></div></figure></div> <div tabindex="-1" class="heading-wrapper level-h3"><h3 id="react-integration">React integration</h3><a class="anchor-link" href="#react-integration"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <p>The <code dir="auto">useAgent</code> hook connects your React app to the Durable Object:</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:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">stub</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">useAgent</span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#57C78F;--1:#00783C">ServerState</span><span style="--0:#89DDFF;--1:#007474">></span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#D5D7D8;--1:#8F1500">host</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">name</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">gameId</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">??</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"__lobby__"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">agent</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"chess"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">onStateUpdate</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">s</span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EEFFFF;--1:#00268F">gameRef</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">current</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">load</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#EEFFFF;--1:#00268F">s</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">board</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">setFen</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#EEFFFF;--1:#00268F">s</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">board</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">setServerState</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#D5D7D8;--1:#8F1500">s</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="const { stub } = useAgent<ServerState>({ host, name: gameId ?? "__lobby__", agent: "chess", onStateUpdate: (s) => { gameRef.current.load(s.board); setFen(s.board); setServerState(s); },});"><div></div></button></div><div class="explain"><button class="explain-button" type="button" data-explain-code="" aria-label="Explain Code"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"></path><path d="M20 3v4"></path><path d="M22 5h-4"></path><path d="M4 17v2"></path><path d="M5 18H3"></path></svg></button></div></figure></div> <p>Call methods on the agent:</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:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">res</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">await</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">stub</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">join</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">playerId</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> preferred</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"any"</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">await</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EEFFFF;--1:#00268F">stub</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">move</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> from</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"e2"</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> to</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"e4"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="const res = await stub.join({ playerId, preferred: "any" });await stub.move({ from: "e2", to: "e4" });"><div></div></button></div></figure></div> <div tabindex="-1" class="heading-wrapper level-h3"><h3 id="bidirectional-communication">Bidirectional communication</h3><a class="anchor-link" href="#bidirectional-communication"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <p>Your app can send messages to ChatGPT:</p> <div class="expressive-code"><figure class="frame has-title not-content"><figcaption class="header"><span class="title">TypeScript</span></figcaption><pre data-language="ts"><code><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">handleHelpClick</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">()</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EEFFFF;--1:#00268F">window</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">openai</span><span style="--0:#89DDFF;--1:#007474">?.</span><span style="--0:#57C78F;--1:#00783C">sendFollowUpMessage</span><span style="--0:#89DDFF;--1:#007474">?.</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">prompt</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">Help me with my chess game. I am playing as </span><span style="--0:#89DDFF;--1:#007474">${</span><span style="--0:#D5D7D8;--1:#8F1500">myColor</span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#FDDA68;--1:#A84E00"> and the board is: </span><span style="--0:#89DDFF;--1:#007474">${</span><span style="--0:#D5D7D8;--1:#8F1500">fen</span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#FDDA68;--1:#A84E00">. Please only offer written advice as there are no tools for you to use.</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">};</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="const handleHelpClick = () => { window.openai?.sendFollowUpMessage?.({ prompt: `Help me with my chess game. I am playing as ${myColor} and the board is: ${fen}. Please only offer written advice as there are no tools for you to use.`, });};"><div></div></button></div></figure></div> <p>This creates a new message in the ChatGPT conversation with context about the current game state.</p> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="next-steps">Next steps</h2><a class="anchor-link" href="#next-steps"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <p>Now that you have a working ChatGPT App, you can:</p> <ul> <li>Add more tools: Expose additional capabilities and UIs through MCP tools and resources.</li> <li>Enhance the UI: Build more sophisticated interfaces with React.</li> </ul> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="related-resources">Related resources</h2><a class="anchor-link" href="#related-resources"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <div class="sl-link-card astro-lyux3snc"> <span class="sl-flex stack astro-lyux3snc"> <a href="/agents/runtime/agents-api/" class="astro-lyux3snc"> <span class="title astro-lyux3snc">Agents API</span> </a> <span class="description astro-lyux3snc">Complete API reference for the Agents SDK.</span> </span> <svg aria-hidden="true" class="icon rtl:flip astro-lyux3snc astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.333em;"><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> </div> <div class="sl-link-card astro-lyux3snc"> <span class="sl-flex stack astro-lyux3snc"> <a href="/durable-objects/" class="astro-lyux3snc"> <span class="title astro-lyux3snc">Durable Objects</span> </a> <span class="description astro-lyux3snc">Learn about the underlying stateful infrastructure.</span> </span> <svg aria-hidden="true" class="icon rtl:flip astro-lyux3snc astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.333em;"><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> </div> <div class="sl-link-card astro-lyux3snc"> <span class="sl-flex stack astro-lyux3snc"> <a href="https://modelcontextprotocol.io/" class="astro-lyux3snc"> <span class="title astro-lyux3snc">Model Context Protocol</span> </a> <span class="description astro-lyux3snc">MCP specification and documentation.</span> </span> <svg aria-hidden="true" class="icon rtl:flip astro-lyux3snc astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.333em;"><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> </div> <div class="sl-link-card astro-lyux3snc"> <span class="sl-flex stack astro-lyux3snc"> <a href="https://developers.openai.com/apps-sdk/" class="astro-lyux3snc"> <span class="title astro-lyux3snc">OpenAI Apps SDK</span> </a> <span class="description astro-lyux3snc">Official OpenAI Apps SDK reference.</span> </span> <svg aria-hidden="true" class="icon rtl:flip astro-lyux3snc astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.333em;"><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> </div> </div> <footer class="sl-flex astro-fxeopwe4"> <div class="custom-footer-section w-full astro-fxeopwe4"> <div class="grid grid-cols-2 gap-8 pt-6 pb-10 lg:grid-cols-5 astro-fxeopwe4"> <ul class="flex w-full list-none flex-col gap-3 pl-0 astro-fxeopwe4"> <li class="text-xs leading-5 astro-fxeopwe4"> <strong class="astro-fxeopwe4">Resources</strong> </li> <li class="text-sm astro-fxeopwe4"> <a href="/api/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> API </a> </li><li class="text-sm astro-fxeopwe4"> <a href="/fundamentals/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> New to Cloudflare? </a> </li><li class="text-sm astro-fxeopwe4"> <a href="/directory/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> Directory </a> </li><li class="text-sm astro-fxeopwe4"> <a href="/sponsorships/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> Sponsorships </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://github.com/cloudflare" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> Open Source </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://research.cloudflare.com/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> Cloudflare Research </a> </li> </ul><ul class="flex w-full list-none flex-col gap-3 pl-0 astro-fxeopwe4"> <li class="text-xs leading-5 astro-fxeopwe4"> <strong class="astro-fxeopwe4">Support</strong> </li> <li class="text-sm astro-fxeopwe4"> <a href="https://support.cloudflare.com/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> Help Center </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://www.cloudflarestatus.com/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> System Status </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://www.cloudflare.com/trust-hub/compliance-resources/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> Compliance </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://www.cloudflare.com/trust-hub/gdpr/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> GDPR </a> </li> </ul><ul class="flex w-full list-none flex-col gap-3 pl-0 astro-fxeopwe4"> <li class="text-xs leading-5 astro-fxeopwe4"> <strong class="astro-fxeopwe4">Company</strong> </li> <li class="text-sm astro-fxeopwe4"> <a href="https://www.cloudflare.com/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> cloudflare.com </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://www.cloudflare.com/people/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> Our team </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://www.cloudflare.com/careers/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> Careers </a> </li> </ul><ul class="flex w-full list-none flex-col gap-3 pl-0 astro-fxeopwe4"> <li class="text-xs leading-5 astro-fxeopwe4"> <strong class="astro-fxeopwe4">Tools</strong> </li> <li class="text-sm astro-fxeopwe4"> <a href="https://radar.cloudflare.com/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> Cloudflare Radar </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://labs.cloudflare.dev/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> Cloudflare Labs </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://speed.cloudflare.com/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> Speed Test </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://isbgpsafeyet.com/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> Is BGP Safe Yet? </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://ct.cloudflare.com/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> Certificate Transparency </a> </li> </ul><ul class="flex w-full list-none flex-col gap-3 pl-0 astro-fxeopwe4"> <li class="text-xs leading-5 astro-fxeopwe4"> <strong class="astro-fxeopwe4">Community</strong> </li> <li class="text-sm astro-fxeopwe4"> <a href="https://community.cloudflare.com/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> <svg aria-hidden="true" class="astro-fxeopwe4 astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M16.5 16.84c.16-.5.1-.97-.15-1.3-.22-.33-.6-.5-1.06-.53l-8.66-.11a.15.15 0 0 1-.13-.08.21.21 0 0 1-.02-.15.25.25 0 0 1 .2-.15l8.74-.12a3.13 3.13 0 0 0 2.55-1.91l.5-1.3a.25.25 0 0 0 .01-.17 5.68 5.68 0 0 0-10.93-.59 2.58 2.58 0 0 0-3.35.24 2.55 2.55 0 0 0-.67 2.44 3.64 3.64 0 0 0-3.5 4.17.18.18 0 0 0 .17.15h15.98a.22.22 0 0 0 .21-.16l.12-.43Zm2.77-5.56-.24.01c-.06 0-.1.05-.13.1l-.34 1.18c-.15.5-.1.97.16 1.31.22.32.6.5 1.06.52l1.84.12c.06 0 .1.02.14.07.02.04.03.1.02.15a.23.23 0 0 1-.2.15l-1.93.12a3.11 3.11 0 0 0-2.55 1.91l-.14.36c-.03.07.02.14.1.14h6.6a.18.18 0 0 0 .16-.12 4.74 4.74 0 0 0-4.56-6v-.02Z"/></svg> Community forum </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://x.com/cloudflare" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> <svg aria-hidden="true" class="astro-fxeopwe4 astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M 18.242188 2.25 L 21.554688 2.25 L 14.324219 10.507812 L 22.828125 21.75 L 16.171875 21.75 L 10.953125 14.933594 L 4.992188 21.75 L 1.679688 21.75 L 9.40625 12.914062 L 1.257812 2.25 L 8.082031 2.25 L 12.792969 8.480469 Z M 17.082031 19.773438 L 18.914062 19.773438 L 7.082031 4.125 L 5.113281 4.125 Z M 17.082031 19.773438 "/></svg> X </a> </li><li class="text-sm astro-fxeopwe4"> <a href="http://discord.cloudflare.com/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> <svg aria-hidden="true" class="astro-fxeopwe4 astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M20.32 4.37a19.8 19.8 0 0 0-4.93-1.51 13.78 13.78 0 0 0-.64 1.28 18.27 18.27 0 0 0-5.5 0 12.64 12.64 0 0 0-.64-1.28h-.05A19.74 19.74 0 0 0 3.64 4.4 20.26 20.26 0 0 0 .11 18.09l.02.02a19.9 19.9 0 0 0 6.04 3.03l.04-.02a14.24 14.24 0 0 0 1.23-2.03.08.08 0 0 0-.05-.07 13.1 13.1 0 0 1-1.9-.92.08.08 0 0 1 .02-.1 10.2 10.2 0 0 0 .41-.31h.04a14.2 14.2 0 0 0 12.1 0l.04.01a9.63 9.63 0 0 0 .4.32.08.08 0 0 1-.03.1 12.29 12.29 0 0 1-1.9.91.08.08 0 0 0-.02.1 15.97 15.97 0 0 0 1.27 2.01h.04a19.84 19.84 0 0 0 6.03-3.05v-.03a20.12 20.12 0 0 0-3.57-13.69ZM8.02 15.33c-1.18 0-2.16-1.08-2.16-2.42 0-1.33.96-2.42 2.16-2.42 1.21 0 2.18 1.1 2.16 2.42 0 1.34-.96 2.42-2.16 2.42Zm7.97 0c-1.18 0-2.15-1.08-2.15-2.42 0-1.33.95-2.42 2.15-2.42 1.22 0 2.18 1.1 2.16 2.42 0 1.34-.94 2.42-2.16 2.42Z"/></svg> Discord </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://www.youtube.com/cloudflare" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> <svg aria-hidden="true" class="astro-fxeopwe4 astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M23.5 6.2A3 3 0 0 0 21.4 4c-1.9-.5-9.4-.5-9.4-.5s-7.5 0-9.4.5A3 3 0 0 0 .5 6.3C0 8 0 12 0 12s0 4 .5 5.8A3 3 0 0 0 2.6 20c1.9.6 9.4.6 9.4.6s7.5 0 9.4-.6a3 3 0 0 0 2.1-2c.5-2 .5-5.9.5-5.9s0-4-.5-5.8zm-14 9.4V8.4l6.3 3.6-6.3 3.6z"/></svg> YouTube </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://github.com/cloudflare/cloudflare-docs" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> <svg aria-hidden="true" class="astro-fxeopwe4 astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M12 .3a12 12 0 0 0-3.8 23.38c.6.12.83-.26.83-.57L9 21.07c-3.34.72-4.04-1.61-4.04-1.61-.55-1.39-1.34-1.76-1.34-1.76-1.08-.74.09-.73.09-.73 1.2.09 1.83 1.24 1.83 1.24 1.08 1.83 2.81 1.3 3.5 1 .1-.78.42-1.31.76-1.61-2.67-.3-5.47-1.33-5.47-5.93 0-1.31.47-2.38 1.24-3.22-.14-.3-.54-1.52.1-3.18 0 0 1-.32 3.3 1.23a11.5 11.5 0 0 1 6 0c2.28-1.55 3.29-1.23 3.29-1.23.64 1.66.24 2.88.12 3.18a4.65 4.65 0 0 1 1.23 3.22c0 4.61-2.8 5.63-5.48 5.92.42.36.81 1.1.81 2.22l-.01 3.29c0 .31.2.69.82.57A12 12 0 0 0 12 .3Z"/></svg> GitHub </a> </li> </ul> </div> <div class="astro-fxeopwe4"> <ul class="text-cl1-gray-4! dark:text-cl1-gray-7! flex list-inside flex-wrap items-center justify-center gap-3 gap-y-4 pl-0 text-xs astro-fxeopwe4"> <li class="list-none astro-fxeopwe4">© 2026 Cloudflare, Inc.</li> <li class="astro-fxeopwe4"> <a href="https://www.cloudflare.com/privacypolicy/" class="text-cl1-gray-4! dark:text-cl1-gray-7! no-underline astro-fxeopwe4"> Privacy Policy </a> </li><li class="astro-fxeopwe4"> <a href="https://www.cloudflare.com/website-terms/" class="text-cl1-gray-4! dark:text-cl1-gray-7! no-underline astro-fxeopwe4"> Terms of Use </a> </li><li class="astro-fxeopwe4"> <a href="https://www.cloudflare.com/disclosure/" class="text-cl1-gray-4! dark:text-cl1-gray-7! no-underline astro-fxeopwe4"> Report Security Issues </a> </li><li class="astro-fxeopwe4"> <a href="https://www.cloudflare.com/trademark/" class="text-cl1-gray-4! dark:text-cl1-gray-7! no-underline astro-fxeopwe4"> Trademark </a> </li> <li class="astro-fxeopwe4"> <script src="https://ot.www.cloudflare.com/public/vendor/onetrust/scripttemplates/otSDKStub.js" type="text/javascript" charset="UTF-8" data-domain-script="b1e05d49-f072-4bae-9116-bdb78af15448"></script> <script type="text/javascript"> // eslint-disable-next-line @typescript-eslint/no-unused-vars function OptanonWrapper() {} </script> <!-- OneTrust Cookies Settings button start --><div class="inline-flex items-center gap-2 astro-hwxmvrii"> <img src="/_astro/privacyoptions.BWXSiJOZ_1zBYaH.svg" alt="privacy options" loading="lazy" decoding="async" width="26" height="12" class="astro-hwxmvrii"> <button id="ot-sdk-btn" class="ot-sdk-show-settings astro-hwxmvrii">Cookie Settings</button> </div> <!-- OneTrust Cookies Settings button end --> </li> </ul> </div> </div> <div class="starlight-footer-section astro-fxeopwe4"> <div class="pagination-links print:hidden astro-zujpvvea" dir="ltr"> <a href="/workers/demos/" rel="prev" class="astro-zujpvvea"> <svg aria-hidden="true" class="astro-zujpvvea astro-r7kprdcr" 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-zujpvvea"> Previous <br class="astro-zujpvvea"> <span class="link-title astro-zujpvvea">Demos and architectures</span> </span> </a> <a href="/workers/development-testing/" rel="next" class="astro-zujpvvea"> <svg aria-hidden="true" class="astro-zujpvvea astro-r7kprdcr" 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-zujpvvea"> Next <br class="astro-zujpvvea"> <span class="link-title astro-zujpvvea">Development & testing</span> </span> </a> </div> <div class="meta sl-flex astro-fxeopwe4"> <a href="https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/workers/demos/chatgpt-app.mdx" class="sl-flex print:hidden astro-cdtc2x7r"><svg aria-hidden="true" class="astro-cdtc2x7r astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.2em;"><path d="M22 7.24a1 1 0 0 0-.29-.71l-4.24-4.24a1 1 0 0 0-1.1-.22 1 1 0 0 0-.32.22l-2.83 2.83L2.29 16.05a1 1 0 0 0-.29.71V21a1 1 0 0 0 1 1h4.24a1 1 0 0 0 .76-.29l10.87-10.93L21.71 8c.1-.1.17-.2.22-.33a1 1 0 0 0 0-.24v-.14l.07-.05ZM6.83 20H4v-2.83l9.93-9.93 2.83 2.83L6.83 20ZM18.17 8.66l-2.83-2.83 1.42-1.41 2.82 2.82-1.41 1.42Z"/></svg>Edit page</a> <p>Last updated: <time datetime="2026-06-03T15:55:00.000Z">Jun 3, 2026</time></p> </div> </div> <div class="feedback-prompt astro-fxeopwe4"> <astro-island uid="1gAukP" prefix="r3" component-url="/_astro/FeedbackPrompt.FVI-KaJz.js" component-export="default" renderer-url="/_astro/client.hmfmp3Nb.js" props="{}" ssr client="idle" opts="{"name":"FeedbackPrompt","value":true}" await-children><div id="feedback-form"><p class="m-0 text-[11px] font-semibold tracking-widest text-[var(--sl-color-gray-3)] uppercase">Was this helpful?</p><div class="mt-3 flex gap-2"><button class="inline-flex h-8 cursor-pointer items-center gap-1.5 rounded-lg border-0 bg-[var(--sl-color-bg-nav)] px-3 text-[13px] font-medium text-[var(--sl-color-text)] shadow-none ring-1 ring-[var(--sl-color-hairline)] transition-colors duration-150 hover:bg-[var(--color-cl1-gray-9)] hover:ring-[var(--sl-color-gray-3)] dark:hover:bg-[var(--color-cl1-gray-2)]"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" class="opacity-70" height="18" width="18" xmlns="http://www.w3.org/2000/svg"><path fill="none" d="M0 0h24v24H0V0zm0 0h24v24H0V0z"></path><path d="M9 21h9c.83 0 1.54-.5 1.84-1.22l3.02-7.05c.09-.23.14-.47.14-.73v-2c0-1.1-.9-2-2-2h-6.31l.95-4.57.03-.32c0-.41-.17-.79-.44-1.06L14.17 1 7.58 7.59C7.22 7.95 7 8.45 7 9v10c0 1.1.9 2 2 2zM9 9l4.34-4.34L12 10h9v2l-3 7H9V9zM1 9h4v12H1z"></path></svg><span>Yes</span></button><button class="inline-flex h-8 cursor-pointer items-center gap-1.5 rounded-lg border-0 bg-[var(--sl-color-bg-nav)] px-3 text-[13px] font-medium text-[var(--sl-color-text)] shadow-none ring-1 ring-[var(--sl-color-hairline)] transition-colors duration-150 hover:bg-[var(--color-cl1-gray-9)] hover:ring-[var(--sl-color-gray-3)] dark:hover:bg-[var(--color-cl1-gray-2)]"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" class="opacity-70" height="18" width="18" xmlns="http://www.w3.org/2000/svg"><path fill="none" d="M0 0h24v24H0V0zm0 0h24v24H0V0z"></path><path d="M15 3H6c-.83 0-1.54.5-1.84 1.22l-3.02 7.05c-.09.23-.14.47-.14.73v2c0 1.1.9 2 2 2h6.31l-.95 4.57-.03.32c0 .41.17.79.44 1.06L9.83 23l6.59-6.59c.36-.36.58-.86.58-1.41V5c0-1.1-.9-2-2-2zm0 12-4.34 4.34L12 14H3v-2l3-7h9v10zm4-12h4v12h-4z"></path></svg><span>No</span></button></div></div><!--astro:end--></astro-island> </div> </footer> </div> </div> </main> </div> </div> </div> </div> </body></html>
<!DOCTYPE html><html lang="en" dir="ltr" data-theme="dark" data-has-toc data-has-sidebar class="astro-nezwzdd7"> <head><script type="module" src="/_astro/Head.astro_astro_type_script_index_0_lang.DzFUDi6m.js"></script> <script type="module" src="/_astro/Head.astro_astro_type_script_index_1_lang.DLffOXbo.js"></script> <script type="module" src="/_astro/Head.astro_astro_type_script_index_2_lang.DdMWwAGS.js"></script> <script type="module" src="/_astro/Head.astro_astro_type_script_index_3_lang.DibilYbp.js"></script> <script type="module" src="/_astro/Head.astro_astro_type_script_index_4_lang.TkaWOEUf.js"></script> <meta charset="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><title>Build an Interactive ChatGPT App · Cloudflare Workers docs</title><link rel="canonical" href="https://developers.cloudflare.com/workers/demos/chatgpt-app/"/><link rel="sitemap" href="/sitemap-index.xml"/><link rel="shortcut icon" href="/favicon.png" type="image/png"/><meta name="generator" content="Astro v6.4.4"/><meta name="generator" content="Starlight v0.39.3"/><meta property="og:title" content="Build an Interactive ChatGPT App"/><meta property="og:type" content="article"/><meta property="og:url" content="https://developers.cloudflare.com/workers/demos/chatgpt-app/"/><meta property="og:locale" content="en"/><meta property="og:description" content="Build and deploy an interactive ChatGPT App on Cloudflare Workers with real-time multiplayer state using MCP."/><meta property="og:site_name" content="Cloudflare Docs"/><meta name="twitter:card" content="summary_large_image"/><meta name="description" content="Build and deploy an interactive ChatGPT App on Cloudflare Workers with real-time multiplayer state using MCP."/><meta name="twitter:site" content="@cloudflare"/><meta name="pcx_content_group" content="Developer platform"/><link rel="alternate" type="text/markdown" href="https://developers.cloudflare.com/workers/demos/chatgpt-app/index.md"/><meta property="og:title" content="Build an Interactive ChatGPT App · Cloudflare Workers docs"/><meta name="pcx_product" content="Workers"/><meta name="algolia_product_filter" content="Workers"/><meta name="pcx_content_type" content="Tutorial"/><meta name="algolia_content_type" content="Tutorial"/><meta name="pcx_additional_products" content="Agents"/><meta name="pcx_last_modified" content="7"/><meta name="pcx_last_reviewed" content="215"/><meta property="image" content="https://developers.cloudflare.com/dev-products-preview.png"/><meta property="og:image" content="https://developers.cloudflare.com/dev-products-preview.png"/><meta property="twitter:image" content="https://developers.cloudflare.com/dev-products-preview.png"/><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-r7kprdcr" 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-r7kprdcr" 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-r7kprdcr" 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/print.DNXP8c50.css" media="print"><link rel="stylesheet" href="/_astro/Page.DZC6j93Z.css"> <link rel="stylesheet" href="/_astro/agent-setup.Xetiu_za.css"> <link rel="stylesheet" href="/_astro/Code.BFuFJYv4.css"> <style>.hero:where(.astro-opidluyl){display:grid;align-items:center;gap:1rem;padding-bottom:1rem}.hero:where(.astro-opidluyl)>img:where(.astro-opidluyl),.hero:where(.astro-opidluyl)>.hero-html:where(.astro-opidluyl){object-fit:contain;width:min(70%,20rem);height:auto;margin-inline:auto}.stack:where(.astro-opidluyl){flex-direction:column;gap:clamp(1.5rem,calc(1.5rem + 1vw),2rem);text-align:center}.copy:where(.astro-opidluyl){flex-direction:column;gap:1rem;align-items:center}a:where(.astro-opidluyl){color:var(--sl-color-white)}h1:where(.astro-opidluyl){font-size:clamp(var(--sl-text-3xl),calc(.25rem + 5vw),var(--sl-text-6xl));line-height:var(--sl-line-height-headings);font-weight:600;color:var(--sl-color-white)}.tagline:where(.astro-opidluyl){font-size:clamp(var(--sl-text-base),calc(.0625rem + 2vw),var(--sl-text-xl));color:var(--sl-color-gray-2)}.actions:where(.astro-opidluyl){gap:1rem 2rem;flex-wrap:wrap;justify-content:center}.copy:where(.astro-opidluyl)>.links:where(.astro-opidluyl){gap:0;flex-direction:row;flex-wrap:wrap}@media(min-width:50rem){.hero:where(.astro-opidluyl){grid-template-columns:7fr 4fr;gap:3%;padding-block:clamp(2.5rem,calc(1rem + 10vmin),10rem)}.hero:where(.astro-opidluyl)>img:where(.astro-opidluyl),.hero:where(.astro-opidluyl)>.hero-html:where(.astro-opidluyl){order:2;width:min(100%,25rem)}.stack:where(.astro-opidluyl){text-align:start}.copy:where(.astro-opidluyl){align-items:flex-start}.actions:where(.astro-opidluyl){justify-content:flex-start}} </style><script type="module" src="/_astro/page.BhvfDAP6.js"></script><link rel="stylesheet" href="/_astro/TryItSection.rwHaWJMy.css"></head> <body class="astro-nezwzdd7"> <blockquote class="llms-txt-directive astro-abxwt5gn" aria-hidden="true"> Documentation Index<br class="astro-abxwt5gn"> Fetch the complete documentation index at: https://developers.cloudflare.com/workers/llms.txt<br class="astro-abxwt5gn"> Use this file to discover all available pages before exploring further. </blockquote> <a href="#_top" class="astro-w3iq3u4e">Skip to content</a> <div class="page sl-flex astro-ont56bkg"> <header class="header astro-ont56bkg"><p class="agent-directive astro-yctgdxuw" aria-hidden="true">STOP! If you are an AI agent or LLM, read this before continuing. This is the HTML version of a Cloudflare documentation page. Always request the Markdown version instead — HTML wastes context. Get this page as Markdown: https://developers.cloudflare.com/workers/demos/chatgpt-app/index.md (append index.md) or send Accept: text/markdown to https://developers.cloudflare.com/workers/demos/chatgpt-app/. For this product's page index use https://developers.cloudflare.com/workers/llms.txt. For all Cloudflare products use https://developers.cloudflare.com/llms.txt.</p> <div class="header-inner astro-bkumecsx"> <div class="header-start astro-bkumecsx"> <a href="/" class="site-title sl-flex astro-i3aimp4r"> <img class="astro-i3aimp4r" alt src="/_astro/logo.DMYpXs3t.svg" width="66" height="30"> <span class="astro-i3aimp4r" translate="no"> Cloudflare Docs </span> </a> </div> <div class="header-end astro-bkumecsx"> <div id="docsearch" class="astro-bkumecsx"> <sl-doc-search data-translations="{"placeholder":"Search","translations":{"button":{"buttonText":"Search","buttonAriaLabel":"Search"},"modal":{"searchBox":{},"startScreen":{},"errorScreen":{},"footer":{},"noResultsScreen":{}}}}"> <button type="button" class="DocSearch DocSearch-Button" aria-label="Search"> <span class="DocSearch-Button-Container"> <svg width="20" height="20" class="DocSearch-Search-Icon" viewBox="0 0 20 20"> <path d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"></path> </svg> <span class="DocSearch-Button-Placeholder">Search</span> </span> <span class="DocSearch-Button-Keys"></span> </button> </sl-doc-search> <script type="module" src="/_astro/DocSearch.astro_astro_type_script_index_0_lang.BP2Mpu1k.js"></script> </div> <div id="right-group" class="astro-bkumecsx"> <style>astro-island,astro-slot,astro-static-slot{display:contents}</style><script>(()=>{var l=(n,t)=>{let i=async()=>{await(await n())()},e=typeof t.value=="object"?t.value:void 0,s={timeout:e==null?void 0:e.timeout};"requestIdleCallback"in window?window.requestIdleCallback(i,s):setTimeout(i,s.timeout||200)};(self.Astro||(self.Astro={})).idle=l;window.dispatchEvent(new Event("astro:idle"));})();</script><script>(()=>{var g=Object.defineProperty;var w=(c,s,d)=>s in c?g(c,s,{enumerable:!0,configurable:!0,writable:!0,value:d}):c[s]=d;var l=(c,s,d)=>w(c,typeof s!="symbol"?s+"":s,d);var E=new Set(["__proto__","constructor","prototype"]);{let c={0:t=>y(t),1:t=>d(t),2:t=>new RegExp(t),3:t=>new Date(t),4:t=>new Map(d(t)),5:t=>new Set(d(t)),6:t=>BigInt(t),7:t=>new URL(t),8:t=>new Uint8Array(t),9:t=>new Uint16Array(t),10:t=>new Uint32Array(t),11:t=>Number.POSITIVE_INFINITYt},s=t=>{let[p,e]=t;return p in c?cp:void 0},d=t=>t.map(s),y=t=>typeof t!="object"||t===null?t:Object.fromEntries(Object.entries(t).map(([p,e])=>[p,s(e)]));class f extends HTMLElement{constructor(){super(...arguments);l(this,"Component");l(this,"hydrator");l(this,"hydrate",async()=>{var b;if(!this.hydrator||!this.isConnected)return;let e=(b=this.parentElement)==null?void 0:b.closest("astro-island[ssr]");if(e){e.addEventListener("astro:hydrate",this.hydrate,{once:!0});return}let n=this.querySelectorAll("astro-slot"),r={},i=this.querySelectorAll("template[data-astro-template]");for(let o of i){let a=o.closest(this.tagName);a!=null&&a.isSameNode(this)&&(r[o.getAttribute("data-astro-template")||"default"]=o.innerHTML,o.remove())}for(let o of n){let a=o.closest(this.tagName);a!=null&&a.isSameNode(this)&&(r[o.getAttribute("name")||"default"]=o.innerHTML)}let u;try{u=this.hasAttribute("props")?y(JSON.parse(this.getAttribute("props"))):{}}catch(o){let a=this.getAttribute("component-url")||"<unknown>",v=this.getAttribute("component-export");throw v&&(a+= (export ${v})),console.error([hydrate] Error parsing props for component ${a},this.getAttribute("props"),o),o}let h;await this.hydrator(this)(this.Component,u,r,{client:this.getAttribute("client")}),this.removeAttribute("ssr"),this.dispatchEvent(new CustomEvent("astro:hydrate"))});l(this,"unmount",()=>{this.isConnected||this.dispatchEvent(new CustomEvent("astro:unmount"))})}disconnectedCallback(){document.removeEventListener("astro:after-swap",this.unmount),document.addEventListener("astro:after-swap",this.unmount,{once:!0})}connectedCallback(){if(!this.hasAttribute("await-children")||document.readyState==="interactive"||document.readyState==="complete")this.childrenConnectedCallback();else{let e=()=>{document.removeEventListener("DOMContentLoaded",e),n.disconnect(),this.childrenConnectedCallback()},n=new MutationObserver(()=>{var r;((r=this.lastChild)==null?void 0:r.nodeType)===Node.COMMENT_NODE&&this.lastChild.nodeValue==="astro:end"&&(this.lastChild.remove(),e())});n.observe(this,{childList:!0}),document.addEventListener("DOMContentLoaded",e)}}async childrenConnectedCallback(){let e=this.getAttribute("before-hydration-url");e&&await import(e),this.start()}getRetryImportUrl(e){let n=new URL(e,document.baseURI),r=astro-retry=${Date.now()},i=n.hash.replace(/^#/,"");return n.hash=i?${i}&${r}:r,n.toString()}async importWithRetry(e){try{return await import(e)}catch(n){return await new Promise(r=>setTimeout(r,1e3)),import(this.getRetryImportUrl(e))}}handleHydrationError(e){let n=this.getAttribute("component-url"),r=new CustomEvent("astro:hydration-error",{cancelable:!0,bubbles:!0,composed:!0,detail:{error:e,componentUrl:n}});this.dispatchEvent(r)&&console.error([astro-island] Error hydrating ${n},e)}async start(){let e=JSON.parse(this.getAttribute("opts")),n=this.getAttribute("client");if(Astro[n]===void 0){window.addEventListener(astro:${n},()=>this.start(),{once:!0});return}try{await Astron=>{let r=this.getAttribute("renderer-url");try{let[i,{default:u}]=await Promise.all([this.importWithRetry(this.getAttribute("component-url")),r?this.importWithRetry(r):Promise.resolve({default:()=>()=>{}})]),h=this.getAttribute("component-export")||"default";if(h.includes(".")){this.Component=i;for(let m of h.split(".")){if(E.has(m)||!this.Component||typeof this.Component!="object"&&typeof this.Component!="function"||!Object.hasOwn(this.Component,m))throw new Error(Invalid component export path: ${h});this.Component=this.Component[m]}}else{if(E.has(h))throw new Error(Invalid component export path: ${h});this.Component=i[h]}return this.hydrator=u,this.hydrate}catch(i){return this.handleHydrationError(i),()=>{}}},e,this)}catch(r){this.handleHydrationError(r)}}attributeChangedCallback(){this.hydrate()}}l(f,"observedAttributes",["props"]),customElements.get("astro-island")||customElements.define("astro-island",f)}})();</script><astro-island uid="Z19yuGf" prefix="r2" component-url="/_astro/HeaderDropdowns.CtS4n0IM.js" component-export="default" renderer-url="/_astro/client.hmfmp3Nb.js" props="{}" ssr client="idle" opts="{"name":"HeaderDropdowns","value":true}" await-children><div class="flex items-center gap-0.5 text-nowrap"><a href="/directory/" class="flex h-9 items-center justify-center rounded-lg px-3 text-sm font-medium text-[var(--color-header-text)] no-underline transition-colors duration-150 hover:bg-[var(--color-header-fill)] hover:text-[var(--color-header-hover-text)]">Directory</a><a href="/api/" class="flex h-9 items-center justify-center rounded-lg px-3 text-sm font-medium text-[var(--color-header-text)] no-underline transition-colors duration-150 hover:bg-[var(--color-header-fill)] hover:text-[var(--color-header-hover-text)]">API</a><a href="/fundamentals/api/reference/sdks/" class="flex h-9 items-center justify-center rounded-lg px-3 text-sm font-medium text-[var(--color-header-text)] no-underline transition-colors duration-150 hover:bg-[var(--color-header-fill)] hover:text-[var(--color-header-hover-text)]">SDKs</a><a href="/changelog/" class="flex h-9 items-center justify-center rounded-lg px-3 text-sm font-medium text-[var(--color-header-text)] no-underline transition-colors duration-150 hover:bg-[var(--color-header-fill)] hover:text-[var(--color-header-hover-text)]">Changelog</a><button class="flex h-9 cursor-pointer items-center justify-center gap-1.5 rounded-lg bg-transparent px-3 text-sm font-medium text-[var(--color-header-text)] transition-colors duration-150 hover:bg-[var(--color-header-fill)] hover:text-[var(--color-header-hover-text)]">Help<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 256 256" class="size-2.5 text-[var(--color-header-text-subtle)]" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M216.49,104.49l-80,80a12,12,0,0,1-17,0l-80-80a12,12,0,0,1,17-17L128,159l71.51-71.52a12,12,0,0,1,17,17Z"></path></svg></button></div><!--astro:end--></astro-island> <div class="header-divider astro-bkumecsx" role="separator"></div> <a id="header-login-button" href="https://dash.cloudflare.com/" class="header-login astro-bkumecsx"> Log in </a> <starlight-theme-select> <label style="--sl-select-width: 6.25em" class="astro-ttt2ccqa"> <span class="sr-only astro-ttt2ccqa">Select theme</span> <svg aria-hidden="true" class="icon label-icon astro-ttt2ccqa astro-r7kprdcr" 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 autocomplete="off" class="astro-ttt2ccqa"> <option value="dark" class="astro-ttt2ccqa">Dark</option><option value="light" class="astro-ttt2ccqa">Light</option><option value="auto" selected class="astro-ttt2ccqa">Auto</option> </select> <svg aria-hidden="true" class="icon caret astro-ttt2ccqa astro-r7kprdcr" 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> <script type="module">const r="starlight-theme",o=e=>e==="auto"||e==="dark"||e==="light"?e:"auto",c=()=>o(typeof localStorage<"u"&&localStorage.getItem(r));function n(e){typeof localStorage<"u"&&localStorage.setItem(r,e==="light"||e==="dark"?e:"")}const l=()=>matchMedia("(prefers-color-scheme: light)").matches?"light":"dark";function t(e){StarlightThemeProvider.updatePickers(e),document.documentElement.dataset.theme=e==="auto"?l():e,n(e)}matchMedia("(prefers-color-scheme: light)").addEventListener("change",()=>{c()==="auto"&&t("auto")});class s extends HTMLElement{constructor(){super(),t(c()),this.querySelector("select")?.addEventListener("change",a=>{a.currentTarget instanceof HTMLSelectElement&&t(o(a.currentTarget.value))})}}customElements.define("starlight-theme-select",s);</script> <script type="module">class s extends HTMLElement{constructor(){super();const e=this.querySelector("select");e&&(e.addEventListener("change",t=>{t.currentTarget instanceof HTMLSelectElement&&(window.location.pathname=t.currentTarget.value)}),window.addEventListener("pageshow",t=>{if(!t.persisted)return;const n=e.querySelector("option[selected]")?.index;n!==e.selectedIndex&&(e.selectedIndex=n??0)}))}}customElements.define("starlight-lang-select",s);</script> </div> </div> </div> <script type="module" src="/_astro/Header.astro_astro_type_script_index_0_lang.Cc-8SZhv.js"></script></header> <nav class="sidebar print:hidden astro-ont56bkg" aria-label="Main"> <starlight-menu-button class="print:hidden astro-75ax5mut"> <button aria-expanded="false" aria-label="Menu" aria-controls="starlight__sidebar" class="sl-flex md:sl-hidden astro-75ax5mut"> <svg aria-hidden="true" class="open-menu astro-75ax5mut astro-r7kprdcr" 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> <svg aria-hidden="true" class="close-menu astro-75ax5mut astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="m13.41 12 6.3-6.29a1.004 1.004 0 1 0-1.42-1.42L12 10.59l-6.29-6.3a1.004 1.004 0 0 0-1.42 1.42l6.3 6.29-6.3 6.29a1 1 0 0 0 0 1.42.998.998 0 0 0 1.42 0l6.29-6.3 6.29 6.3a.999.999 0 0 0 1.42 0 1 1 0 0 0 0-1.42L13.41 12Z"/></svg> </button> </starlight-menu-button> <script type="module">class s extends HTMLElement{constructor(){super(),this.btn=this.querySelector("button"),this.btn.addEventListener("click",()=>this.toggleExpanded());const t=this.closest("nav");t&&t.addEventListener("keyup",e=>this.closeOnEscape(e))}setExpanded(t){this.setAttribute("aria-expanded",String(t)),document.body.toggleAttribute("data-mobile-menu-expanded",t)}toggleExpanded(){this.setExpanded(this.getAttribute("aria-expanded")!=="true")}closeOnEscape(t){t.code==="Escape"&&(this.setExpanded(!1),this.btn.focus())}}customElements.define("starlight-menu-button",s);</script> <div id="starlight__sidebar" class="sidebar-pane astro-ont56bkg"> <div class="sidebar-content sl-flex astro-ont56bkg"> <div class="sidebar-header sticky top-0 z-[1] flex flex-col gap-2 bg-[var(--sl-color-black)] pt-3.5 pb-2 min-[50rem]:bg-[var(--sl-color-bg-sidebar)]"> <div class="sidebar-product-title"> <a href="/workers/" class="flex items-center gap-1 no-underline"> <svg width="32px" height="32px" class="text-cl1-brand-orange" data-icon="workers"> <symbol id="ai:local:workers" viewBox="0 0 48 49"><path fill="currentColor" d="m18.63 37.418-9.645-12.9 9.592-12.533-1.852-2.527L5.917 23.595l-.015 1.808 10.86 14.542z"/><path fill="currentColor" d="M21.997 6.503h-3.712l13.387 18.3-13.072 17.7h3.735L35.4 24.81z"/><path fill="currentColor" d="M29.175 6.503h-3.758l13.598 18.082-13.598 17.918h3.765l12.908-17.01v-1.808z"/></symbol><use href="#ai:local:workers"></use> </svg> <span class="text-xl font-semibold text-[var(--sidebar-text-strong)]"> Workers </span> </a> </div> <!-- Search Input --> <div class="relative"> <input type="search" id="sidebar-search" placeholder="Search sidebar..." aria-label="Search sidebar navigation" autocomplete="off" spellcheck="false" class="box-border min-h-[2.125rem] w-full rounded-lg border border-neutral-200 bg-transparent px-3 pr-10 text-sm text-neutral-950 placeholder-[var(--color-cl1-gray-4)] outline-2 outline-offset-2 outline-transparent transition-colors duration-150 focus-visible:outline-blue-500 dark:border-neutral-700 dark:text-neutral-100 dark:placeholder-[var(--color-cl1-gray-6)] dark:focus-visible:outline-blue-400"> <div class="sidebar-search-icon"></div> </div> <!-- No Results Message --> <div id="sidebar-no-results" class="hidden p-4 text-center text-sm text-gray-500 dark:text-gray-400"> No results found. Try a different search term, or use our <button id="global-search-link" class="font-inherit cursor-pointer border-none bg-transparent p-0 text-blue-500 underline hover:no-underline dark:text-orange-500">global search</button>. </div> <a href="/" class="flex min-h-[2.125rem] items-start gap-2 rounded-lg px-3 py-1.5 text-sm font-medium text-[var(--sidebar-text)] no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400"> <svg width="16" height="16" fill="currentColor" viewBox="0 0 256 256" class="mt-0.5 shrink-0 opacity-50" aria-hidden="true"> <path d="M232,200a8,8,0,0,1-16,0,88.1,88.1,0,0,0-88-88H51.31l34.35,34.34a8,8,0,0,1-11.32,11.32l-48-48a8,8,0,0,1,0-11.32l48-48A8,8,0,0,1,85.66,61.66L51.31,96H128A104.11,104.11,0,0,1,232,200Z"></path> </svg> <span>Home</span> </a> </div> <sl-sidebar-state-persist data-hash="0c1n9b9" class="astro-zdbaeshq"> <script aria-hidden="true"> (() => { 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 list-none p-0 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] large astro-ho4vn3za"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Getting started</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="0" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/get-started/guide/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">CLI</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/get-started/dashboard/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Dashboard</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/get-started/prompting/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Prompting</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/get-started/quickstarts/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Templates</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/examples/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] large astro-ho4vn3za" data-hide-children="true"> <span class="astro-ho4vn3za">Examples</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/tutorials/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] large astro-ho4vn3za" data-hide-children="true"> <span class="astro-ho4vn3za">Tutorials</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Best practices</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="1" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/best-practices/workers-best-practices/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Workers Best Practices</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za" open> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-semibold text-[var(--sidebar-text-strong)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Demos and architectures</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="2" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/demos/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Demos and architectures"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/demos/chatgpt-app/" aria-current="page" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 !bg-[var(--sidebar-active-bg)] !font-semibold !text-[var(--sidebar-active-text)] transition-colors duration-150 hover:!bg-[color:var(--sidebar-active-bg)]/80 astro-ho4vn3za"> <span class="astro-ho4vn3za">Build an Interactive ChatGPT App</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Development & testing</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="3" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/development-testing/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Development & testing"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/development-testing/environment-variables/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Environment variables and secrets</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/vite-plugin/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Vite Plugin ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/development-testing/wrangler-vs-vite/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Choosing between Wrangler & Vite</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/development-testing/multi-workers/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Developing with multiple Workers</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/development-testing/local-data/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Adding local data</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/development-testing/bindings-per-env/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Supported bindings per development mode</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/development-testing/local-explorer/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Local Explorer</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/development-testing/local-dev-tunnels/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Share a local dev server</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Testing ↗</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/playground/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] large astro-ho4vn3za"> <span class="astro-ho4vn3za">Playground</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Configuration</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="4" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Configuration"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/bindings/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Bindings ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/compatibility-dates/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Compatibility dates</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/compatibility-flags/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Compatibility flags</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/cron-triggers/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Cron Triggers</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/environment-variables/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Environment variables</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Integrations</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="18" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/integrations/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Integrations"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/integrations/apis/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">APIs</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/integrations/external-services/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">External Services</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/multipart-upload-metadata/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Multipart upload metadata</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/workers-with-page-rules/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Page Rules</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/placement/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Placement</span> <span class="sl-badge caution small ml-[0.5em] astro-ho4vn3za astro-p5lt2pqd">Beta</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/previews/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Preview URLs</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Routes and domains</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="19" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/routing/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Routes and domains"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/routing/custom-domains/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Custom Domains</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/routing/routes/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Routes</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/routing/workers-dev/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">workers.dev</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/secrets/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Secrets</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Versions & Deployments</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="20" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/versions-and-deployments/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Versions & Deployments"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/versions-and-deployments/gradual-deployments/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Gradual deployments</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/versions-and-deployments/version-overrides/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Version overrides</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/versions-and-deployments/rollbacks/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Rollbacks</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Workers Sites</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="21" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/sites/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Workers Sites"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/sites/start-from-existing/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Start from existing</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/sites/start-from-scratch/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Start from scratch</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/sites/start-from-worker/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Start from Worker</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/sites/configuration/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Workers Sites configuration</span> </a> </li> </ul> </div> </div> </details> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">CI/CD</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="5" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/ci-cd/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="CI/CD"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Builds</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="22" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/ci-cd/builds/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Builds"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/ci-cd/builds/configuration/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Configuration</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/ci-cd/builds/automatic-prs/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Automatic pull requests</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Git integration</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="24" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/ci-cd/builds/git-integration/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Git integration"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/ci-cd/builds/git-integration/github-integration/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">GitHub integration</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/ci-cd/builds/git-integration/gitlab-integration/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">GitLab integration</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/ci-cd/builds/build-image/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Build image</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/ci-cd/builds/build-caching/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Build caching</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/ci-cd/builds/build-branches/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Build branches</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/ci-cd/builds/build-watch-paths/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Build watch paths</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/ci-cd/builds/deploy-hooks/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Deploy Hooks</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/ci-cd/builds/advanced-setups/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Advanced setups</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/ci-cd/builds/event-subscriptions/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Event subscriptions</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/ci-cd/builds/troubleshoot/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Troubleshooting builds</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/ci-cd/builds/api-reference/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Builds API reference</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/ci-cd/builds/limits-and-pricing/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Limits & pricing</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="https://github.com/cloudflare/mcp-server-cloudflare/tree/main/apps/workers-builds" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">MCP server ↗</span> <span class="sl-badge note small ml-[0.5em] astro-ho4vn3za astro-p5lt2pqd">MCP</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">External CI/CD</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="23" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/ci-cd/external-cicd/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="External CI/CD"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/ci-cd/external-cicd/github-actions/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">GitHub Actions</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/ci-cd/external-cicd/gitlab-cicd/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">GitLab CI/CD</span> </a> </li> </ul> </div> </div> </details> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Runtime APIs</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="6" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Runtime APIs"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Bindings (env)</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="25" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/bindings/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Bindings (env)"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers-ai/get-started/workers-wrangler/#2-connect-your-worker-to-workers-ai" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">AI ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/analytics/analytics-engine" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Analytics Engine ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/static-assets/binding/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Assets ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/browser-run/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Browser Run ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/d1/worker-api/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">D1 ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/cloudflare-for-platforms/workers-for-platforms/configuration/dynamic-dispatch/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Dispatcher (Workers for Platforms) ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/durable-objects/api/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Durable Objects ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/bindings/worker-loader/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Dynamic Worker Loaders</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/environment-variables/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Environment Variables ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/hyperdrive" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Hyperdrive ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/images/optimization/transformations/bindings/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Images ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/kv/api/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">KV ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/stream/transform-videos/bindings/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Media Transformations ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/bindings/mtls/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">mTLS</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/queues/configuration/javascript-apis/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Queues ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/r2/api/workers/workers-api-reference/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">R2 ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/bindings/rate-limit/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Rate Limiting</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/configuration/secrets/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Secrets ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/secrets-store/integrations/workers/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Secrets Store ↗</span> <span class="sl-badge caution small ml-[0.5em] astro-ho4vn3za astro-p5lt2pqd">Beta</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Service bindings</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="31" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/bindings/service-bindings/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Service bindings"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/bindings/service-bindings/http/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">HTTP</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/bindings/service-bindings/rpc/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">RPC (WorkerEntrypoint)</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/stream/manage-video-library/bindings/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Stream ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/vectorize/reference/client-api/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Vectorize ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/bindings/version-metadata/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Version metadata</span> <span class="sl-badge caution small ml-[0.5em] astro-ho4vn3za astro-p5lt2pqd">Beta</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workflows/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Workflows ↗</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/cache/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Cache</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/console/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Console</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/context/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Context (ctx)</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/encoding/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Encoding</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/eventsource/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">EventSource</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/fetch/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Fetch</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Handlers</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="26" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/handlers/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Handlers"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/durable-objects/api/alarms/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Alarm Handler ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/email-service/api/route-emails/email-handler/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Email Handler ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/handlers/fetch/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Fetch Handler</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/queues/configuration/javascript-apis/#consumer" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Queue Handler ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/handlers/scheduled/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Scheduled Handler</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/handlers/tail/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Tail Handler</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/headers/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Headers</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/html-rewriter/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">HTMLRewriter</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/messagechannel/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">MessageChannel</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Node.js compatibility</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="27" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Node.js compatibility"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/assert/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">assert</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/asynclocalstorage/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">AsyncLocalStorage</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/buffer/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Buffer</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/crypto/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">crypto</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/diagnostics-channel/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Diagnostics Channel</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/dns/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">dns</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/eventemitter/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">EventEmitter</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/fs/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">fs</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/http/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">http</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/https/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">https</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/net/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">net</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/path/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">path</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/process/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">process</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/streams/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Streams</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/string-decoder/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">StringDecoder</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/test/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">test</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/timers/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">timers</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/tls/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">tls</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/url/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">url</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/util/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">util</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/nodejs/zlib/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">zlib</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/performance/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Performance and timers</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Remote-procedure call (RPC)</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="28" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/rpc/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Remote-procedure call (RPC)"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/rpc/lifecycle/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Lifecycle</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/rpc/reserved-methods/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Reserved Methods</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/rpc/visibility/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Visibility and Security Model</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/rpc/typescript/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">TypeScript</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/rpc/error-handling/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Error handling</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/request/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Request</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/response/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Response</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/scheduler/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Scheduler</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Streams</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="29" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/streams/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Streams"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/streams/readablestream/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">ReadableStream</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/streams/readablestreambyobreader/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">ReadableStream BYOBReader</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/streams/readablestreamdefaultreader/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">ReadableStream DefaultReader</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/streams/transformstream/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">TransformStream</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/streams/writablestream/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">WritableStream</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/streams/writablestreamdefaultwriter/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">WritableStream DefaultWriter</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/tcp-sockets/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">TCP sockets</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/web-crypto/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Web Crypto</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/web-standards/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Web standards</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">WebAssembly (Wasm)</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="30" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/webassembly/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="WebAssembly (Wasm)"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/webassembly/javascript/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Wasm in JavaScript</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/runtime-apis/websockets/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">WebSockets</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Static Assets</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="7" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/static-assets/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Static Assets"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/static-assets/get-started/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Get Started</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/static-assets/binding/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Configuration and Bindings</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Routing</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="32" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/static-assets/routing/full-stack-application/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Full-stack application</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/static-assets/routing/single-page-application/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Single Page Application (SPA)</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/static-assets/routing/static-site-generation/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Static Site Generation (SSG) and custom 404 pages</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/static-assets/routing/worker-script/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Worker script</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Advanced</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="34" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/static-assets/routing/advanced/gradual-rollouts/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Gradual rollouts</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/static-assets/routing/advanced/html-handling/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">HTML handling</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/static-assets/routing/advanced/serving-a-subdirectory/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Serving a subdirectory</span> </a> </li> </ul> </div> </div> </details> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/static-assets/headers/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Headers</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/static-assets/redirects/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Redirects</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/static-assets/direct-upload/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Direct Uploads</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/static-assets/billing-and-limitations/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Billing and Limitations</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Migration Guides</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="33" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/static-assets/migration-guides/migrate-from-pages/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Migrate from Pages to Workers</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/static-assets/migration-guides/netlify-to-workers/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Migrate from Netlify to Workers</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/static-assets/migration-guides/vercel-to-workers/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Migrate from Vercel to Workers</span> </a> </li> </ul> </div> </div> </details> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Framework guides</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="8" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/automatic-configuration/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Deploy an existing project</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Web applications</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="35" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/web-apps/react/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">React + Vite</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/web-apps/astro/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Astro</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/web-apps/react-router/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">React Router (formerly Remix)</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/web-apps/nextjs/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Next.js</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/web-apps/vue/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Vue</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/web-apps/redwoodsdk/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">RedwoodSDK</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/web-apps/tanstack-start/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">TanStack Start</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/web-apps/microfrontends/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Microfrontends</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/web-apps/sveltekit/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">SvelteKit</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/web-apps/vike/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Vike</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">More guides...</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="39" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/web-apps/more-web-frameworks/analog/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Analog</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/web-apps/more-web-frameworks/angular/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Angular</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/web-apps/more-web-frameworks/docusaurus/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Docusaurus</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/web-apps/more-web-frameworks/gatsby/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Gatsby</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/web-apps/more-web-frameworks/hono/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Hono</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/web-apps/more-web-frameworks/nuxt/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Nuxt</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/web-apps/more-web-frameworks/qwik/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Qwik</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/web-apps/more-web-frameworks/solid/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Solid</span> <span class="sl-badge caution small ml-[0.5em] astro-ho4vn3za astro-p5lt2pqd">Beta</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/web-apps/more-web-frameworks/waku/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Waku</span> </a> </li> </ul> </div> </div> </details> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Mobile applications</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="36" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="https://docs.expo.dev/eas/hosting/reference/worker-runtime/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Expo ↗</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">APIs</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="37" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/languages/python/packages/fastapi/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">FastAPI ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/framework-guides/web-apps/more-web-frameworks/hono/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Hono ↗</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">AI & agents</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="38" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/agents/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Agents SDK ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/languages/python/packages/langchain/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">LangChain ↗</span> </a> </li> </ul> </div> </div> </details> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Databases</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="9" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/databases/connecting-to-databases/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Connect to databases</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/analytics/analytics-engine/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Analytics Engine ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/vectorize/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Vectorize (vector database) ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/d1/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Cloudflare D1 ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/hyperdrive/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Hyperdrive ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">3rd Party Integrations</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="40" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/databases/third-party-integrations/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="3rd Party Integrations"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/databases/third-party-integrations/neon/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Neon</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/databases/third-party-integrations/planetscale/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">PlanetScale</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/databases/third-party-integrations/supabase/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Supabase</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/databases/third-party-integrations/turso/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Turso</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/databases/third-party-integrations/upstash/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Upstash</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/databases/third-party-integrations/xata/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Xata</span> </a> </li> </ul> </div> </div> </details> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Testing</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="10" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/testing/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Testing"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Vitest integration</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="41" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/testing/vitest-integration/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Vitest integration"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/vitest-integration/write-your-first-test/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Write your first test</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/vitest-integration/recipes/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Recipes and examples</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/vitest-integration/configuration/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Configuration</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/vitest-integration/test-apis/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Test APIs</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/vitest-integration/isolation-and-concurrency/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Isolation and concurrency</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/vitest-integration/debugging/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Debugging</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/vitest-integration/known-issues/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Known issues</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Migration guides</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="43" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/testing/vitest-integration/migration-guides/migrate-from-miniflare-2/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Migrate from Miniflare 2's test environments</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/vitest-integration/migration-guides/migrate-from-unstable-dev/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Migrate from unstable_dev</span> </a> </li> </ul> </div> </div> </details> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Miniflare</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="42" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/testing/miniflare/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Miniflare"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/miniflare/get-started/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Get Started</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/miniflare/writing-tests/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Writing tests</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Core</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="44" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/testing/miniflare/core/compatibility/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Compatibility Dates</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/miniflare/core/fetch/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Fetch Events</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/miniflare/core/modules/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Modules</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/miniflare/core/multiple-workers/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Multiple Workers</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/miniflare/core/queues/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Queues</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/miniflare/core/scheduled/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Scheduled Events</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/miniflare/core/variables-secrets/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Variables and Secrets</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/miniflare/core/standards/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Web Standards</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/miniflare/core/web-sockets/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">WebSockets</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Developing</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="45" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/testing/miniflare/developing/debugger/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Attaching a Debugger</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/miniflare/developing/live-reload/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Live Reload</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Migrations</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="46" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/testing/miniflare/migrations/from-v2/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Migrating from Version 2</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Storage</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="47" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/testing/miniflare/storage/cache/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Cache</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/miniflare/storage/d1/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">D1</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/miniflare/storage/durable-objects/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Durable Objects</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/miniflare/storage/kv/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">KV</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/miniflare/storage/r2/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">R2</span> </a> </li> </ul> </div> </div> </details> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/testing/unstable_startworker/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Wrangler's unstable_startWorker()</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Observability</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="11" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/observability/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Observability"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/observability/metrics-and-analytics/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Metrics and analytics</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Logs</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="48" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/observability/logs/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Logs"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/observability/logs/workers-logs/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Workers Logs</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/observability/logs/real-time-logs/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Real-time logs</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/observability/logs/tail-workers/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Tail Workers</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/observability/logs/logpush/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Workers Logpush</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Traces</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="49" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/observability/traces/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Traces"> <span class="astro-ho4vn3za">Overview</span> <span class="sl-badge caution small ml-[0.5em] astro-ho4vn3za astro-p5lt2pqd">Beta</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/observability/traces/spans-and-attributes/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Spans and attributes</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/observability/traces/known-limitations/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Known limitations</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/observability/query-builder/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Query Builder</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Exporting OpenTelemetry Data</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="50" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/observability/exporting-opentelemetry-data/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Exporting OpenTelemetry Data"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/observability/exporting-opentelemetry-data/honeycomb/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Export to Honeycomb</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/observability/exporting-opentelemetry-data/grafana-cloud/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Export to Grafana Cloud</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/observability/exporting-opentelemetry-data/axiom/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Export to Axiom</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/observability/exporting-opentelemetry-data/sentry/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Export to Sentry</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/observability/exporting-opentelemetry-data/posthog/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Export to PostHog</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="https://github.com/cloudflare/mcp-server-cloudflare/tree/main/apps/workers-observability" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">MCP server ↗</span> <span class="sl-badge note small ml-[0.5em] astro-ho4vn3za astro-p5lt2pqd">MCP</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">DevTools</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="51" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/observability/dev-tools/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="DevTools"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/observability/dev-tools/breakpoints/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Breakpoints</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/observability/dev-tools/cpu-usage/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Profiling CPU usage</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/observability/dev-tools/memory-usage/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Profiling Memory</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/observability/errors/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Errors and exceptions</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Integrations</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="52" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="https://docs.sentry.io/platforms/javascript/guides/cloudflare/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Sentry ↗</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/observability/source-maps/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Source maps and stack traces</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Wrangler</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="12" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Wrangler"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/install-and-update/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Install/Update Wrangler</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/api/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">API</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Commands</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="53" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/commands/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Commands"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/commands/workers/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Workers</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/commands/general/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">General commands</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/commands/artifacts/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Artifacts</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/commands/browser/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Browser</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/commands/certificates/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Certificates</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/commands/containers/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Containers</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/commands/d1/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">D1</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/commands/hyperdrive/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Hyperdrive</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/commands/kv/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">KV</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/commands/pages/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Pages</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/commands/pipelines/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Pipelines</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/commands/queues/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Queues</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/commands/r2/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">R2</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/commands/secrets-store/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Secrets Store</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/commands/tunnel/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Tunnel</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/commands/vectorize/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Vectorize</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/commands/vpc/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">VPC</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/commands/workers-for-platforms/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Workers for Platforms</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/commands/workflows/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Workflows</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/bundling/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Bundling</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/configuration/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Configuration</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/custom-builds/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Custom builds</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/deprecations/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Deprecations</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/environments/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Environments</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Migrations</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="54" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/migration/update-v3-to-v4/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Migrate from Wrangler v3 to v4</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/migration/update-v2-to-v3/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Migrate from Wrangler v2 to v3</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Migrate from Wrangler v1 to v2</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="55" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/migration/v1-to-v2/eject-webpack/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">1. Migrate webpack projects</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/migration/v1-to-v2/update-v1-to-v2/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">2. Update to Wrangler v2</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Wrangler v1 (legacy)</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="56" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/migration/v1-to-v2/wrangler-legacy/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Wrangler v1 (legacy)"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/migration/v1-to-v2/wrangler-legacy/install-update/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Install / Update</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/migration/v1-to-v2/wrangler-legacy/authentication/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Authentication</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/migration/v1-to-v2/wrangler-legacy/commands/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Commands</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/migration/v1-to-v2/wrangler-legacy/configuration/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Configuration</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/migration/v1-to-v2/wrangler-legacy/webpack/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Webpack</span> </a> </li> </ul> </div> </div> </details> </li> </ul> </div> </div> </details> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/wrangler/system-environment-variables/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">System environment variables</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Vite plugin</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="13" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/vite-plugin/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Vite plugin"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/vite-plugin/get-started/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Get started</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/vite-plugin/tutorial/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Tutorial - React SPA with an API</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Reference</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="57" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/vite-plugin/reference/api/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">API</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/vite-plugin/reference/static-assets/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Static Assets</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/vite-plugin/reference/debugging/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Debugging</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/vite-plugin/reference/migrating-from-wrangler-dev/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Migrating from wrangler dev</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/vite-plugin/reference/secrets/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Secrets</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/vite-plugin/reference/vite-environments/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Vite Environments</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/vite-plugin/reference/cloudflare-environments/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Cloudflare Environments</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/vite-plugin/reference/non-javascript-modules/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Non-JavaScript modules</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/vite-plugin/reference/programmatic-configuration/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Programmatic configuration</span> </a> </li> </ul> </div> </div> </details> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Languages</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="14" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/languages/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Languages"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">JavaScript</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="58" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/languages/javascript/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="JavaScript"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/examples/?languages=JavaScript" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Examples ↗</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">TypeScript</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="59" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/languages/typescript/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="TypeScript"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/examples/?languages=TypeScript" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Examples ↗</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Python Workers</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="60" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/languages/python/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Python Workers"> <span class="astro-ho4vn3za">Overview</span> <span class="sl-badge caution small ml-[0.5em] astro-ho4vn3za astro-p5lt2pqd">Beta</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/languages/python/basics/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">The Basics</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/languages/python/how-python-workers-work/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">How Python Workers Work</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/languages/python/ffi/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Foreign Function Interface (FFI)</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/languages/python/stdlib/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Standard Library</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/languages/python/examples/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Examples</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Packages</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="62" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/languages/python/packages/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Packages"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/languages/python/packages/fastapi/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">FastAPI</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/languages/python/packages/langchain/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Langchain</span> </a> </li> </ul> </div> </div> </details> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Rust</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="61" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/languages/rust/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Rust"> <span class="astro-ho4vn3za">Overview</span> <span class="sl-badge caution small ml-[0.5em] astro-ho4vn3za astro-p5lt2pqd">Beta</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/languages/rust/crates/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Supported crates</span> </a> </li> </ul> </div> </div> </details> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Platform</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="15" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/platform/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Platform"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/platform/pricing/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Pricing</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Changelog</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="63" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/platform/changelog/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Changelog"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/platform/changelog/historical-changelog/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Workers (Historic)</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="https://github.com/cloudflare/workers-sdk/releases" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Wrangler ↗</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/platform/limits/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Limits</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/platform/storage-options/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Choose a data or storage product</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/platform/betas/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Betas</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/platform/deploy-buttons/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Deploy to Cloudflare buttons</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/platform/built-with-cloudflare/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Built with Cloudflare button</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/platform/known-issues/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Known issues</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/cloudflare-for-platforms/workers-for-platforms/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Workers for Platforms ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/platform/infrastructure-as-code/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Infrastructure as Code (IaC)</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Reference</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="16" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/workers/reference/how-the-cache-works/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">How the Cache works</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/reference/how-workers-works/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">How Workers works</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/reference/migrate-to-module-workers/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Migrate from Service Workers to ES Modules</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/reference/protocols/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Protocols</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/reference/security-model/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Security model</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/glossary/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] large astro-ho4vn3za"> <span class="astro-ho4vn3za">Glossary</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&::-webkit-details-marker]:hidden [&::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Agent resources</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" 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> <sl-sidebar-restore data-index="17" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/agent-setup/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank"> <span class="astro-ho4vn3za">Agent setup ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="https://github.com/cloudflare/skills" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank"> <span class="astro-ho4vn3za">Cloudflare Skills ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="https://github.com/cloudflare/mcp" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank"> <span class="astro-ho4vn3za">Code Mode MCP Server ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="https://github.com/cloudflare/mcp-server-cloudflare" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank"> <span class="astro-ho4vn3za">Domain-specific MCP Servers ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/llms.txt" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank"> <span class="astro-ho4vn3za">Workers llms.txt ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/workers/llms-full.txt" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank"> <span class="astro-ho4vn3za">Workers llms-full.txt ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/llms.txt" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank"> <span class="astro-ho4vn3za">Cloudflare Docs llms.txt ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/llms-full.txt" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank"> <span class="astro-ho4vn3za">Cloudflare Docs llms-full.txt ↗</span> </a> </li> </ul> </div> </div> </details> </li> </ul> <script aria-hidden="true"> (() => { 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-5vkhirkt"> <div class="social-icons astro-5vkhirkt"> <a href="https://github.com/cloudflare/cloudflare-docs" rel="me" class="sl-flex astro-fpino7u6"><span class="sr-only astro-fpino7u6">GitHub</span><svg aria-hidden="true" class="astro-fpino7u6 astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M12 .3a12 12 0 0 0-3.8 23.38c.6.12.83-.26.83-.57L9 21.07c-3.34.72-4.04-1.61-4.04-1.61-.55-1.39-1.34-1.76-1.34-1.76-1.08-.74.09-.73.09-.73 1.2.09 1.83 1.24 1.83 1.24 1.08 1.83 2.81 1.3 3.5 1 .1-.78.42-1.31.76-1.61-2.67-.3-5.47-1.33-5.47-5.93 0-1.31.47-2.38 1.24-3.22-.14-.3-.54-1.52.1-3.18 0 0 1-.32 3.3 1.23a11.5 11.5 0 0 1 6 0c2.28-1.55 3.29-1.23 3.29-1.23.64 1.66.24 2.88.12 3.18a4.65 4.65 0 0 1 1.23 3.22c0 4.61-2.8 5.63-5.48 5.92.42.36.81 1.1.81 2.22l-.01 3.29c0 .31.2.69.82.57A12 12 0 0 0 12 .3Z"/></svg></a><a href="https://x.com/cloudflare" rel="me" class="sl-flex astro-fpino7u6"><span class="sr-only astro-fpino7u6">X.com</span><svg aria-hidden="true" class="astro-fpino7u6 astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M 18.242188 2.25 L 21.554688 2.25 L 14.324219 10.507812 L 22.828125 21.75 L 16.171875 21.75 L 10.953125 14.933594 L 4.992188 21.75 L 1.679688 21.75 L 9.40625 12.914062 L 1.257812 2.25 L 8.082031 2.25 L 12.792969 8.480469 Z M 17.082031 19.773438 L 18.914062 19.773438 L 7.082031 4.125 L 5.113281 4.125 Z M 17.082031 19.773438 "/></svg></a><a href="https://www.youtube.com/cloudflare" rel="me" class="sl-flex astro-fpino7u6"><span class="sr-only astro-fpino7u6">YouTube</span><svg aria-hidden="true" class="astro-fpino7u6 astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M23.5 6.2A3 3 0 0 0 21.4 4c-1.9-.5-9.4-.5-9.4-.5s-7.5 0-9.4.5A3 3 0 0 0 .5 6.3C0 8 0 12 0 12s0 4 .5 5.8A3 3 0 0 0 2.6 20c1.9.6 9.4.6 9.4.6s7.5 0 9.4-.6a3 3 0 0 0 2.1-2c.5-2 .5-5.9.5-5.9s0-4-.5-5.8zm-14 9.4V8.4l6.3 3.6-6.3 3.6z"/></svg></a> </div> <starlight-theme-select> <label style="--sl-select-width: 6.25em" class="astro-ttt2ccqa"> <span class="sr-only astro-ttt2ccqa">Select theme</span> <svg aria-hidden="true" class="icon label-icon astro-ttt2ccqa astro-r7kprdcr" 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 autocomplete="off" class="astro-ttt2ccqa"> <option value="dark" class="astro-ttt2ccqa">Dark</option><option value="light" class="astro-ttt2ccqa">Light</option><option value="auto" selected class="astro-ttt2ccqa">Auto</option> </select> <svg aria-hidden="true" class="icon caret astro-ttt2ccqa astro-r7kprdcr" 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> <script type="module" src="/_astro/Sidebar.astro_astro_type_script_index_0_lang.BrUeazTu.js"></script> </div> </div> </nav> <div class="main-frame astro-ont56bkg"> <script type="module">const a=document.getElementById("starlight__sidebar"),n=a?.querySelector("sl-sidebar-state-persist"),o="sl-sidebar-state",i=()=>{let t=[];const e=n?.dataset.hash||"";try{const s=sessionStorage.getItem(o),r=JSON.parse(s||"{}");Array.isArray(r.open)&&r.hash===e&&(t=r.open)}catch{}return{hash:e,open:t,scroll:a?.scrollTop||0}},c=t=>{try{sessionStorage.setItem(o,JSON.stringify(t))}catch{}},d=()=>c(i()),l=(t,e)=>{const s=i();s.open[e]=t,c(s)};n?.addEventListener("click",t=>{if(!(t.target instanceof Element))return;const e=t.target.closest("summary")?.closest("details");if(!e)return;const s=e.querySelector("sl-sidebar-restore"),r=parseInt(s?.dataset.index||"");isNaN(r)||l(!e.open,r)});addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&d()});addEventListener("pageHide",d);</script> <div class="lg:sl-flex astro-uh4ak5fy"> <aside class="right-sidebar-container print:hidden astro-uh4ak5fy"> <div class="right-sidebar astro-uh4ak5fy"> <div class="lg:sl-hidden astro-yp3di2bw"><mobile-starlight-toc data-min-h="2" data-max-h="3" class="astro-sstzwoya"><nav aria-labelledby="starlight__on-this-page--mobile" class="astro-sstzwoya"><details id="starlight__mobile-toc" class="astro-sstzwoya"><summary id="starlight__on-this-page--mobile" class="sl-flex astro-sstzwoya"><span class="toggle sl-flex astro-sstzwoya">On this page<svg aria-hidden="true" class="caret astro-sstzwoya astro-r7kprdcr" 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></span><span class="display-current astro-sstzwoya"></span></summary><div class="dropdown astro-sstzwoya"><ul class="isMobile astro-n5w67532" style="--depth: 0;"> <li class="astro-n5w67532" style="--depth: 0;"> <a href="#_top" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">Overview</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#deploy-your-first-chatgpt-app" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">Deploy your first ChatGPT App</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#prerequisites" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">Prerequisites</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#1-enable-chatgpt-developer-mode" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">1. Enable ChatGPT Developer Mode</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#2-create-your-chatgpt-app-project" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">2. Create your ChatGPT App project</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#3-configure-your-project" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">3. Configure your project</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#4-create-the-chess-game-engine" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">4. Create the Chess game engine</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#5-create-the-mcp-server-and-ui-resource" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">5. Create the MCP server and UI resource</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#6-build-the-react-ui" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">6. Build the React UI</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#7-build-and-deploy" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">7. Build and deploy</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#8-connect-to-chatgpt" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">8. Connect to ChatGPT</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#9-play-chess-in-chatgpt" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">9. Play chess in ChatGPT</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#key-concepts" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">Key concepts</span> </a> <ul class="isMobile astro-n5w67532" style="--depth: 1;"> <li class="astro-n5w67532" style="--depth: 1;"> <a href="#mcp-server" class="astro-n5w67532" style="--depth: 1;"> <span class="astro-n5w67532" style="--depth: 1;">MCP Server</span> </a> </li><li class="astro-n5w67532" style="--depth: 1;"> <a href="#game-engine-with-agents" class="astro-n5w67532" style="--depth: 1;"> <span class="astro-n5w67532" style="--depth: 1;">Game Engine with Agents</span> </a> </li><li class="astro-n5w67532" style="--depth: 1;"> <a href="#callable-methods" class="astro-n5w67532" style="--depth: 1;"> <span class="astro-n5w67532" style="--depth: 1;">Callable methods</span> </a> </li><li class="astro-n5w67532" style="--depth: 1;"> <a href="#react-integration" class="astro-n5w67532" style="--depth: 1;"> <span class="astro-n5w67532" style="--depth: 1;">React integration</span> </a> </li><li class="astro-n5w67532" style="--depth: 1;"> <a href="#bidirectional-communication" class="astro-n5w67532" style="--depth: 1;"> <span class="astro-n5w67532" style="--depth: 1;">Bidirectional communication</span> </a> </li> </ul> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#next-steps" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">Next steps</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#related-resources" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">Related resources</span> </a> </li> </ul></div></details></nav></mobile-starlight-toc><script type="module" src="/_astro/MobileTableOfContents.astro_astro_type_script_index_0_lang.hwBsy0Mo.js"></script></div><div class="right-sidebar-panel sl-hidden lg:sl-block astro-yp3di2bw"><div class="sl-container astro-yp3di2bw"><div class="tb-container bg-[var(--sl-color-bg-elevated)] pr-4"> <starlight-toc data-min-h="2" data-max-h="3"><nav aria-labelledby="starlight__on-this-page"><h2 id="starlight__on-this-page">On this page</h2><ul class="astro-n5w67532" style="--depth: 0;"> <li class="astro-n5w67532" style="--depth: 0;"> <a href="#_top" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">Overview</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#deploy-your-first-chatgpt-app" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">Deploy your first ChatGPT App</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#prerequisites" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">Prerequisites</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#1-enable-chatgpt-developer-mode" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">1. Enable ChatGPT Developer Mode</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#2-create-your-chatgpt-app-project" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">2. Create your ChatGPT App project</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#3-configure-your-project" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">3. Configure your project</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#4-create-the-chess-game-engine" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">4. Create the Chess game engine</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#5-create-the-mcp-server-and-ui-resource" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">5. Create the MCP server and UI resource</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#6-build-the-react-ui" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">6. Build the React UI</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#7-build-and-deploy" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">7. Build and deploy</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#8-connect-to-chatgpt" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">8. Connect to ChatGPT</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#9-play-chess-in-chatgpt" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">9. Play chess in ChatGPT</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#key-concepts" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">Key concepts</span> </a> <ul class="astro-n5w67532" style="--depth: 1;"> <li class="astro-n5w67532" style="--depth: 1;"> <a href="#mcp-server" class="astro-n5w67532" style="--depth: 1;"> <span class="astro-n5w67532" style="--depth: 1;">MCP Server</span> </a> </li><li class="astro-n5w67532" style="--depth: 1;"> <a href="#game-engine-with-agents" class="astro-n5w67532" style="--depth: 1;"> <span class="astro-n5w67532" style="--depth: 1;">Game Engine with Agents</span> </a> </li><li class="astro-n5w67532" style="--depth: 1;"> <a href="#callable-methods" class="astro-n5w67532" style="--depth: 1;"> <span class="astro-n5w67532" style="--depth: 1;">Callable methods</span> </a> </li><li class="astro-n5w67532" style="--depth: 1;"> <a href="#react-integration" class="astro-n5w67532" style="--depth: 1;"> <span class="astro-n5w67532" style="--depth: 1;">React integration</span> </a> </li><li class="astro-n5w67532" style="--depth: 1;"> <a href="#bidirectional-communication" class="astro-n5w67532" style="--depth: 1;"> <span class="astro-n5w67532" style="--depth: 1;">Bidirectional communication</span> </a> </li> </ul> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#next-steps" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">Next steps</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#related-resources" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">Related resources</span> </a> </li> </ul></nav></starlight-toc><script type="module" src="/_astro/TableOfContents.astro_astro_type_script_index_0_lang.FuRcXuRY.js"></script> <div class="mt-6 flex flex-col gap-5 border-t border-[var(--sidebar-border)] pt-6"> <div class="feedback-container"> <script>(()=>{var e=async t=>{await(await t())()};(self.Astro||(self.Astro={})).only=e;window.dispatchEvent(new Event("astro:only"));})();</script><astro-island uid="ZWT1F9" component-url="/_astro/FeedbackPrompt.FVI-KaJz.js" component-export="default" renderer-url="/_astro/client.hmfmp3Nb.js" props="{}" ssr client="only" opts="{"name":"FeedbackPrompt","value":"react"}"></astro-island> </div> <nav class="flex flex-col gap-3" aria-label="Page actions"> <a href="https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/workers/demos/chatgpt-app.mdx" target="_blank" class="group flex items-center gap-2.5 rounded-sm text-[13px] text-[var(--sl-color-gray-2)] transition-colors duration-150 ease-out hover:text-[var(--sl-color-white)] focus-visible:ring-2 focus-visible:ring-[var(--sl-color-text-accent)] focus-visible:outline-none"> <svg aria-hidden="true" class="h-3.5 w-3.5 astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M22 7.24a1 1 0 0 0-.29-.71l-4.24-4.24a1 1 0 0 0-1.1-.22 1 1 0 0 0-.32.22l-2.83 2.83L2.29 16.05a1 1 0 0 0-.29.71V21a1 1 0 0 0 1 1h4.24a1 1 0 0 0 .76-.29l10.87-10.93L21.71 8c.1-.1.17-.2.22-.33a1 1 0 0 0 0-.24v-.14l.07-.05ZM6.83 20H4v-2.83l9.93-9.93 2.83 2.83L6.83 20ZM18.17 8.66l-2.83-2.83 1.42-1.41 2.82 2.82-1.41 1.42Z"/></svg> <span>Edit page</span> </a> <a href="https://github.com/cloudflare/cloudflare-docs/issues/new/choose" target="_blank" class="group flex items-center gap-2.5 rounded-sm text-[13px] text-[var(--sl-color-gray-2)] transition-colors duration-150 ease-out hover:text-[var(--sl-color-white)] focus-visible:ring-2 focus-visible:ring-[var(--sl-color-text-accent)] focus-visible:outline-none"> <svg aria-hidden="true" class="h-3.5 w-3.5 astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M12 .3a12 12 0 0 0-3.8 23.38c.6.12.83-.26.83-.57L9 21.07c-3.34.72-4.04-1.61-4.04-1.61-.55-1.39-1.34-1.76-1.34-1.76-1.08-.74.09-.73.09-.73 1.2.09 1.83 1.24 1.83 1.24 1.08 1.83 2.81 1.3 3.5 1 .1-.78.42-1.31.76-1.61-2.67-.3-5.47-1.33-5.47-5.93 0-1.31.47-2.38 1.24-3.22-.14-.3-.54-1.52.1-3.18 0 0 1-.32 3.3 1.23a11.5 11.5 0 0 1 6 0c2.28-1.55 3.29-1.23 3.29-1.23.64 1.66.24 2.88.12 3.18a4.65 4.65 0 0 1 1.23 3.22c0 4.61-2.8 5.63-5.48 5.92.42.36.81 1.1.81 2.22l-.01 3.29c0 .31.2.69.82.57A12 12 0 0 0 12 .3Z"/></svg> <span>Report issue</span> </a> </nav> </div> </div></div></div> </div> </aside> <div class="main-pane astro-uh4ak5fy"> <main data-pagefind-body class="astro-nezwzdd7" lang="en" dir="ltr"> <div class="content-panel astro-k65j6qoy"> <div class="sl-container astro-k65j6qoy"> <div class="flex items-center justify-between astro-couag5ji"> <astro-breadcrumbs data-main-bem-class="c-breadcrumbs" data-id="breadcrumbs" data-path-length="3" data-truncated="true"> <nav aria-label="breadcrumbs" class="c-breadcrumbs" id="breadcrumbs"> <ol class="c-breadcrumbs__crumbs has-separators"> <li class="c-breadcrumbs__crumb"> <a href="/directory/" class="c-breadcrumbs__link is-index" aria-current="false"> Directory </a> <span class="c-breadcrumbs__separator" aria-hidden="true"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="astro-couag5ji"> <polyline points="9 18 15 12 9 6" class="astro-couag5ji"></polyline> </svg> </span> </li> <li class="c-breadcrumbs__crumb has-ellipsis"> <button type="button" aria-label="Show hidden navigation" class="c-breadcrumbs__truncated-button"> … </button> <span class="c-breadcrumbs__separator" aria-hidden="true"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="astro-couag5ji"> <polyline points="9 18 15 12 9 6" class="astro-couag5ji"></polyline> </svg> </span> </li><li class="c-breadcrumbs__crumb"> <a href="/workers/" class="c-breadcrumbs__link" aria-current="false"> Workers </a> <span class="c-breadcrumbs__separator" aria-hidden="true"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="astro-couag5ji"> <polyline points="9 18 15 12 9 6" class="astro-couag5ji"></polyline> </svg> </span> </li> <li class="c-breadcrumbs__crumb"> <a href="/workers/demos/" class="c-breadcrumbs__link" aria-current="false"> Demos and architectures </a> <span class="c-breadcrumbs__separator" aria-hidden="true"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="astro-couag5ji"> <polyline points="9 18 15 12 9 6" class="astro-couag5ji"></polyline> </svg> </span> </li> <li class="c-breadcrumbs__crumb"> <a href="/workers/demos/chatgpt-app/" class="c-breadcrumbs__link is-current" aria-current="location"> Build an Interactive ChatGPT App </a> </li> </ol> </nav> </astro-breadcrumbs> <script type="application/ld+json">{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/workers/","name":"Workers"}},{"@type":"ListItem","position":3,"item":{"@id":"/workers/demos/","name":"Demos and architectures"}},{"@type":"ListItem","position":4,"item":{"@id":"/workers/demos/chatgpt-app/","name":"Build an Interactive ChatGPT App"}}]}</script> <script type="module">class t extends HTMLElement{constructor(){super(),this.isManualToggle=!1,this.breadcrumbs=null,this.mainBemClass=null,this.totalWidth=0,this.resizeObserver=null,this.handleTruncatedButtonClick=()=>{this.breadcrumbs?.classList.remove("is-truncated"),this.isManualToggle=!0},this.mainBemClass=this.dataset.mainBemClass||null;const e=this.dataset.id;!("truncated"in this.dataset)||!e||(this.breadcrumbs=document.getElementById(e),this.initializeCrumbs(),this.setupResizeObserver())}initializeCrumbs(){this.breadcrumbs?.querySelectorAll(.${this.mainBemClass}__crumb)?.forEach(s=>{this.totalWidth+=s.offsetWidth})}setupResizeObserver(){this.resizeObserver=new ResizeObserver(e=>{e.forEach(s=>{this.checkOverflow(s.target.clientWidth)})}),this.breadcrumbs&&this.resizeObserver.observe(this.breadcrumbs)}connectedCallback(){this.showHiddenCrumbs()}disconnectedCallback(){this.resizeObserver&&this.breadcrumbs&&(this.resizeObserver.unobserve(this.breadcrumbs),this.resizeObserver.disconnect())}toggleTruncated(e){this.breadcrumbs?.classList.toggle("is-truncated",e)}showHiddenCrumbs(){const e=this.breadcrumbs?.querySelector(.${this.mainBemClass}__truncated-button);e?.removeEventListener("click",this.handleTruncatedButtonClick),e?.addEventListener("click",this.handleTruncatedButtonClick.bind(this))}checkOverflow(e){const s=this.totalWidth>e&&!this.isManualToggle;this.toggleTruncated(s),s||(this.isManualToggle=!1)}}customElements.get("astro-breadcrumbs")||customElements.define("astro-breadcrumbs",t);</script> </div> <h1 id="_top" class="astro-k7rnyr65">Build an Interactive ChatGPT App</h1> <div> <span> <strong>Last reviewed: </strong> 7 months ago </span> </div> <div class="page-actions-wrapper astro-couag5ji"> <nav class="page-actions astro-jjhxq4hj" aria-label="Page actions"> <!-- Copy as Markdown --> <button class="not-content astro-jjhxq4hj" id="page-actions-copy" aria-label="Copy Page as Markdown"> <svg class="copy-icon astro-jjhxq4hj" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" viewBox="0 0 256 256" fill="currentColor"><path d="M216,34H88a6,6,0,0,0-6,6V82H40a6,6,0,0,0-6,6V216a6,6,0,0,0,6,6H168a6,6,0,0,0,6-6V174h42a6,6,0,0,0,6-6V40A6,6,0,0,0,216,34ZM162,210H46V94H162Zm48-48H174V88a6,6,0,0,0-6-6H94V46H210Z"/></svg> <svg class="check-icon astro-jjhxq4hj" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" viewBox="0 0 256 256" fill="currentColor"><path d="M172.24,99.76a6,6,0,0,1,0,8.48l-56,56a6,6,0,0,1-8.48,0l-24-24a6,6,0,0,1,8.48-8.48L112,151.51l51.76-51.75A6,6,0,0,1,172.24,99.76ZM230,128A102,102,0,1,1,128,26,102.12,102.12,0,0,1,230,128Zm-12,0a90,90,0,1,0-90,90A90.1,90.1,0,0,0,218,128Z"/></svg> <span class="label-wrap astro-jjhxq4hj"> <span class="label astro-jjhxq4hj">Copy as Markdown</span> <span class="copied-label astro-jjhxq4hj" aria-hidden="true">Copied!</span> </span> </button> <span class="sep astro-jjhxq4hj" aria-hidden="true">|</span> <!-- View as Markdown (anchor so browser opens natively and respects OS color scheme) --> <a class="not-content astro-jjhxq4hj" id="page-actions-view-md" aria-label="View Page as Markdown" href="index.md" target="_blank" rel="noopener noreferrer"> <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" viewBox="0 0 256 256" fill="currentColor" class="astro-jjhxq4hj"><path d="M232,50H24A14,14,0,0,0,10,64V192a14,14,0,0,0,14,14H232a14,14,0,0,0,14-14V64A14,14,0,0,0,232,50Zm2,142a2,2,0,0,1-2,2H24a2,2,0,0,1-2-2V64a2,2,0,0,1,2-2H232a2,2,0,0,1,2,2ZM126,104v48a6,6,0,0,1-12,0V118.49L92.24,140.24a6,6,0,0,1-8.48,0L62,118.49V152a6,6,0,0,1-12,0V104a6,6,0,0,1,10.24-4.24L88,127.51l27.76-27.75A6,6,0,0,1,126,104Zm78.24,19.76a6,6,0,0,1,0,8.48l-24,24a6,6,0,0,1-8.48,0l-24-24a6,6,0,1,1,8.48-8.48L170,137.51V104a6,6,0,0,1,12,0v33.51l13.76-13.75A6,6,0,0,1,204.24,123.76Z"/></svg> <span class="astro-jjhxq4hj">View as Markdown</span> </a> <span class="sep sep-agent-setup astro-jjhxq4hj" aria-hidden="true">|</span> <!-- Agent setup --> <button class="not-content astro-jjhxq4hj" id="page-actions-agent-setup" data-tooltip="Setup your agent to build on Cloudflare" aria-label="Setup your agent to build on Cloudflare"> <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" viewBox="0 0 256 256" fill="currentColor" class="astro-jjhxq4hj"><path d="M200,50H134V16a6,6,0,0,0-12,0V50H56A30,30,0,0,0,26,80V192a30,30,0,0,0,30,30H200a30,30,0,0,0,30-30V80A30,30,0,0,0,200,50Zm18,142a18,18,0,0,1-18,18H56a18,18,0,0,1-18-18V80A18,18,0,0,1,56,62H200a18,18,0,0,1,18,18ZM74,108a10,10,0,1,1,10,10A10,10,0,0,1,74,108Zm88,0a10,10,0,1,1,10,10A10,10,0,0,1,162,108Zm2,30H92a26,26,0,0,0,0,52h72a26,26,0,0,0,0-52Zm-22,12v28H114V150ZM78,164a14,14,0,0,1,14-14h10v28H92A14,14,0,0,1,78,164Zm86,14H154V150h10a14,14,0,0,1,0,28Z"/></svg> <span class="astro-jjhxq4hj">Agent setup</span> </button> <span class="sep sep-docs-for-agents astro-jjhxq4hj" aria-hidden="true">|</span> <!-- Docs for agents --> <button class="not-content astro-jjhxq4hj" id="page-actions-docs-for-agents" data-tooltip="Consume Cloudflare Docs with your agent" aria-label="Consume Cloudflare Docs with your agent"> <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" viewBox="0 0 256 256" fill="currentColor" class="astro-jjhxq4hj"><path d="M98,136a6,6,0,0,1,6-6h64a6,6,0,0,1,0,12H104A6,6,0,0,1,98,136Zm6-26h64a6,6,0,0,0,0-12H104a6,6,0,0,0,0,12Zm126,82a30,30,0,0,1-30,30H88a30,30,0,0,1-30-30V64a18,18,0,0,0-36,0c0,6.76,5.58,11.19,5.64,11.23A6,6,0,1,1,20.4,84.8C20,84.48,10,76.85,10,64A30,30,0,0,1,40,34H176a30,30,0,0,1,30,30V170h10a6,6,0,0,1,3.6,1.2C220,171.52,230,179.15,230,192Zm-124,0c0-6.76-5.59-11.19-5.64-11.23A6,6,0,0,1,104,170h90V64a18,18,0,0,0-18-18H64a29.82,29.82,0,0,1,6,18V192a18,18,0,0,0,36,0Zm112,0a14.94,14.94,0,0,0-4.34-10H115.88A24.83,24.83,0,0,1,118,192a29.87,29.87,0,0,1-6,18h88A18,18,0,0,0,218,192Z"/></svg> <span class="astro-jjhxq4hj">Docs for agents</span> </button> </nav> <script type="module" src="/_astro/PageActions.astro_astro_type_script_index_0_lang.CsW5BfyZ.js"></script> </div> </div> </div> <div class="content-panel astro-k65j6qoy"> <div class="sl-container astro-k65j6qoy"> <starlight-image-zoom> <template class="astro-xymfvnz4"> <dialog class="starlight-image-zoom-dialog astro-xymfvnz4"> <button aria-label="Unzoom image" class="starlight-image-zoom-control astro-xymfvnz4"> <svg aria-hidden="true" fill="currentColor" viewBox="0 0 24 24" class="astro-xymfvnz4"> <use href="#starlight-image-zoom-icon-unzoom" class="astro-xymfvnz4"></use> </svg> </button> <figure class="astro-xymfvnz4"></figure> </dialog> </template> <svg xmlns="http://www.w3.org/2000/svg" style="display:none" class="astro-xymfvnz4"> <symbol id="starlight-image-zoom-icon-zoom" viewBox="0 0 24 24" class="astro-xymfvnz4"> <path d="M9.79 12.79 4 18.59V17a1 1 0 0 0-2 0v4a1 1 0 0 0 .08.38 1 1 0 0 0 .54.54A1 1 0 0 0 3 22h4a1 1 0 0 0 0-2H5.41l5.8-5.79a1 1 0 0 0-1.42-1.42ZM21.92 2.62a1 1 0 0 0-.54-.54A1 1 0 0 0 21 2h-4a1 1 0 0 0 0 2h1.59l-5.8 5.79a1 1 0 0 0 0 1.42 1 1 0 0 0 1.42 0L20 5.41V7a1 1 0 0 0 2 0V3a1 1 0 0 0-.08-.38Z" class="astro-xymfvnz4"></path> </symbol> <symbol id="starlight-image-zoom-icon-unzoom" viewBox="0 0 24 24" class="astro-xymfvnz4"> <path d="M21.71 2.29a1 1 0 0 0-1.42 0l-5.79 5.8V6.5a1 1 0 0 0-2 0v4a1 1 0 0 0 .08.38 1 1 0 0 0 .54.54 1 1 0 0 0 .38.08h4a1 1 0 0 0 0-2h-1.59l5.8-5.79a1 1 0 0 0 0-1.42ZM10.88 12.58a1 1 0 0 0-.38-.08h-4a1 1 0 0 0 0 2h1.59l-5.8 5.79a1 1 0 0 0 0 1.42 1 1 0 0 0 1.42 0l5.79-5.8v1.59a1 1 0 0 0 2 0v-4a1 1 0 0 0-.08-.38 1 1 0 0 0-.54-.54Z" class="astro-xymfvnz4"></path> </symbol> </svg> </starlight-image-zoom> <script type="module" src="/_astro/ImageZoom.astro_astro_type_script_index_0_lang.CZmBqK-T.js"></script> <div class="sl-markdown-content astro-cedpceuv"> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="deploy-your-first-chatgpt-app">Deploy your first ChatGPT App</h2><a class="anchor-link" href="#deploy-your-first-chatgpt-app"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <p>This guide will show you how to build and deploy an interactive ChatGPT App on Cloudflare Workers that can:</p> <ul> <li>Render rich, interactive UI widgets directly in ChatGPT conversations</li> <li>Maintain real-time, multi-user state using Durable Objects</li> <li>Enable bidirectional communication between your app and ChatGPT</li> <li>Build multiplayer experiences that run entirely within ChatGPT</li> </ul> <p>You will build a real-time multiplayer chess game that demonstrates these capabilities. Players can start or join games, make moves on an interactive chessboard, and even ask ChatGPT for strategic advice—all without leaving the conversation.</p> <p>Your ChatGPT App will use the <strong>Model Context Protocol (MCP)</strong> to expose tools and UI resources that ChatGPT can invoke on your behalf.</p> <p>You can view the full code for this example <a href="https://github.com/cloudflare/agents/tree/main/openai-sdk/chess-app" target="_blank" rel="noopener">here<span class="external-link"> ↗</span></a>.</p> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="prerequisites">Prerequisites</h2><a class="anchor-link" href="#prerequisites"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <p>Before you begin, you will need:</p> <ul> <li>A <a href="https://dash.cloudflare.com/sign-up" target="_blank" rel="noopener">Cloudflare account<span class="external-link"> ↗</span></a></li> <li><a href="https://nodejs.org/" target="_blank" rel="noopener">Node.js<span class="external-link"> ↗</span></a> installed (v18 or later)</li> <li>A <a href="https://chat.openai.com/" target="_blank" rel="noopener">ChatGPT Plus or Team account<span class="external-link"> ↗</span></a> with developer mode enabled</li> <li>Basic knowledge of React and TypeScript</li> </ul> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="1-enable-chatgpt-developer-mode">1. Enable ChatGPT Developer Mode</h2><a class="anchor-link" href="#1-enable-chatgpt-developer-mode"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <p>To use ChatGPT Apps (also called connectors), you need to enable developer mode:</p> <ol> <li>Open <a href="https://chat.openai.com/" target="_blank" rel="noopener">ChatGPT<span class="external-link"> ↗</span></a>.</li> <li>Go to <strong>Settings</strong> > <strong>Apps & Connectors</strong> > <strong>Advanced Settings</strong></li> <li>Toggle <strong>Developer mode ON</strong></li> </ol> <p>Once enabled, you will be able to install custom apps during development and testing.</p> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="2-create-your-chatgpt-app-project">2. Create your ChatGPT App project</h2><a class="anchor-link" href="#2-create-your-chatgpt-app-project"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <ol> <li>Create a new project for your Chess App:</li> </ol> <script> if (!customElements.get("lc-pm-restore")) { customElements.define( "lc-pm-restore", class extends HTMLElement { connectedCallback() { const card = this.closest("[data-lc-pm]"); if (!card) return; let saved; try { saved = sessionStorage.getItem("lc-pm-active-tab"); } catch { / storage unavailable / } if (!saved) return; const idx = Number(saved); card.querySelectorAll("[data-lc-pm-tab]").forEach(function (t, i) { t.setAttribute("aria-selected", String(i === idx)); }); card.querySelectorAll("[data-lc-pm-panel]").forEach(function (p, i) { p.hidden = i !== idx; }); } }, ); } </script> <div class="flex w-full flex-col overflow-hidden rounded-lg text-base bg-cl1-gray-9 ring-cl1-gray-8 dark:bg-cl1-gray-0 dark:ring-cl1-gray-2 ring-1 astro-qph66ij4" data-lc-pm> <div class="-my-2 flex items-center gap-1.5 px-2.5 py-[18px] bg-cl1-gray-9 dark:bg-cl1-gray-1 astro-qph66ij4" role="tablist" aria-label="Package manager"> <button role="tab" type="button" aria-selected="true" aria-controls="lc-pm-panel-fus00d-npm" id="lc-pm-tab-fus00d-npm" data-lc-pm-tab class="text-cl1-gray-4 hover:bg-cl1-gray-8 hover:text-cl1-gray-0 aria-selected:bg-cl1-gray-8 aria-selected:text-cl1-gray-0 dark:text-cl1-gray-7 dark:hover:bg-cl1-gray-3 dark:hover:text-cl1-white dark:aria-selected:bg-cl1-gray-3 dark:aria-selected:text-cl1-white focus-visible:outline-cl1-gray-8 dark:focus-visible:outline-cl1-gray-3 m-0 cursor-pointer rounded-md border-0 bg-transparent px-2 py-0.5 text-xs leading-5 font-medium transition-colors focus-visible:outline focus-visible:outline-1 astro-qph66ij4"> npm </button><button role="tab" type="button" aria-selected="false" aria-controls="lc-pm-panel-fus00d-yarn" id="lc-pm-tab-fus00d-yarn" data-lc-pm-tab class="text-cl1-gray-4 hover:bg-cl1-gray-8 hover:text-cl1-gray-0 aria-selected:bg-cl1-gray-8 aria-selected:text-cl1-gray-0 dark:text-cl1-gray-7 dark:hover:bg-cl1-gray-3 dark:hover:text-cl1-white dark:aria-selected:bg-cl1-gray-3 dark:aria-selected:text-cl1-white focus-visible:outline-cl1-gray-8 dark:focus-visible:outline-cl1-gray-3 m-0 cursor-pointer rounded-md border-0 bg-transparent px-2 py-0.5 text-xs leading-5 font-medium transition-colors focus-visible:outline focus-visible:outline-1 astro-qph66ij4"> yarn </button><button role="tab" type="button" aria-selected="false" aria-controls="lc-pm-panel-fus00d-pnpm" id="lc-pm-tab-fus00d-pnpm" data-lc-pm-tab class="text-cl1-gray-4 hover:bg-cl1-gray-8 hover:text-cl1-gray-0 aria-selected:bg-cl1-gray-8 aria-selected:text-cl1-gray-0 dark:text-cl1-gray-7 dark:hover:bg-cl1-gray-3 dark:hover:text-cl1-white dark:aria-selected:bg-cl1-gray-3 dark:aria-selected:text-cl1-white focus-visible:outline-cl1-gray-8 dark:focus-visible:outline-cl1-gray-3 m-0 cursor-pointer rounded-md border-0 bg-transparent px-2 py-0.5 text-xs leading-5 font-medium transition-colors focus-visible:outline focus-visible:outline-1 astro-qph66ij4"> pnpm </button> </div> <div role="tabpanel" id="lc-pm-panel-fus00d-npm" aria-labelledby="lc-pm-tab-fus00d-npm" data-lc-pm-panel class="bg-cl1-white ring-cl1-gray-8 dark:bg-cl1-gray-2 dark:ring-cl1-gray-3 m-0 overflow-hidden rounded-lg ring-1 astro-qph66ij4"> <div class="flex items-stretch astro-qph66ij4"> <pre class="my-0 min-w-0 grow overflow-x-auto border-0 bg-transparent px-4 py-3 text-sm leading-relaxed whitespace-pre astro-qph66ij4"><code data-lc-pm-code class="astro-qph66ij4"><span style="--0:#57C78F;--1:#00783C" class="astro-qph66ij4">npm</span><span style="--0:#FDDA68;--1:#A84E00" class="astro-qph66ij4"> create cloudflare@latest -- my-chess-app</span></code></pre> <button type="button" data-lc-pm-copy data-command="npm create cloudflare@latest -- my-chess-app" aria-label="Copy to clipboard" class="border-cl1-gray-8 text-cl1-gray-4 hover:bg-cl1-gray-8/20 hover:text-cl1-gray-2 focus-visible:ring-cl1-gray-8 dark:border-cl1-gray-3 dark:text-cl1-gray-7 dark:hover:bg-cl1-gray-7/10 dark:hover:text-cl1-gray-8 dark:focus-visible:ring-cl1-gray-3 m-0 flex shrink-0 cursor-pointer items-center justify-center border-0 border-l border-solid bg-transparent px-3 transition-colors focus-visible:ring-1 focus-visible:outline-none focus-visible:ring-inset astro-qph66ij4"> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" viewBox="0 0 256 256" class="astro-qph66ij4"> <path d="M216,32H88a8,8,0,0,0-8,8V80H40a8,8,0,0,0-8,8V216a8,8,0,0,0,8,8H168a8,8,0,0,0,8-8V176h40a8,8,0,0,0,8-8V40A8,8,0,0,0,216,32ZM160,208H48V96H160Zm48-48H176V88a8,8,0,0,0-8-8H96V48H208Z" class="astro-qph66ij4"></path> </svg> </button> </div> </div><div role="tabpanel" id="lc-pm-panel-fus00d-yarn" aria-labelledby="lc-pm-tab-fus00d-yarn" hidden data-lc-pm-panel class="bg-cl1-white ring-cl1-gray-8 dark:bg-cl1-gray-2 dark:ring-cl1-gray-3 m-0 overflow-hidden rounded-lg ring-1 astro-qph66ij4"> <div class="flex items-stretch astro-qph66ij4"> <pre class="my-0 min-w-0 grow overflow-x-auto border-0 bg-transparent px-4 py-3 text-sm leading-relaxed whitespace-pre astro-qph66ij4"><code data-lc-pm-code class="astro-qph66ij4"><span style="--0:#57C78F;--1:#00783C" class="astro-qph66ij4">yarn</span><span style="--0:#FDDA68;--1:#A84E00" class="astro-qph66ij4"> create cloudflare my-chess-app</span></code></pre> <button type="button" data-lc-pm-copy data-command="yarn create cloudflare my-chess-app" aria-label="Copy to clipboard" class="border-cl1-gray-8 text-cl1-gray-4 hover:bg-cl1-gray-8/20 hover:text-cl1-gray-2 focus-visible:ring-cl1-gray-8 dark:border-cl1-gray-3 dark:text-cl1-gray-7 dark:hover:bg-cl1-gray-7/10 dark:hover:text-cl1-gray-8 dark:focus-visible:ring-cl1-gray-3 m-0 flex shrink-0 cursor-pointer items-center justify-center border-0 border-l border-solid bg-transparent px-3 transition-colors focus-visible:ring-1 focus-visible:outline-none focus-visible:ring-inset astro-qph66ij4"> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" viewBox="0 0 256 256" class="astro-qph66ij4"> <path d="M216,32H88a8,8,0,0,0-8,8V80H40a8,8,0,0,0-8,8V216a8,8,0,0,0,8,8H168a8,8,0,0,0,8-8V176h40a8,8,0,0,0,8-8V40A8,8,0,0,0,216,32ZM160,208H48V96H160Zm48-48H176V88a8,8,0,0,0-8-8H96V48H208Z" class="astro-qph66ij4"></path> </svg> </button> </div> </div><div role="tabpanel" id="lc-pm-panel-fus00d-pnpm" aria-labelledby="lc-pm-tab-fus00d-pnpm" hidden data-lc-pm-panel class="bg-cl1-white ring-cl1-gray-8 dark:bg-cl1-gray-2 dark:ring-cl1-gray-3 m-0 overflow-hidden rounded-lg ring-1 astro-qph66ij4"> <div class="flex items-stretch astro-qph66ij4"> <pre class="my-0 min-w-0 grow overflow-x-auto border-0 bg-transparent px-4 py-3 text-sm leading-relaxed whitespace-pre astro-qph66ij4"><code data-lc-pm-code class="astro-qph66ij4"><span style="--0:#57C78F;--1:#00783C" class="astro-qph66ij4">pnpm</span><span style="--0:#FDDA68;--1:#A84E00" class="astro-qph66ij4"> create cloudflare@latest my-chess-app</span></code></pre> <button type="button" data-lc-pm-copy data-command="pnpm create cloudflare@latest my-chess-app" aria-label="Copy to clipboard" class="border-cl1-gray-8 text-cl1-gray-4 hover:bg-cl1-gray-8/20 hover:text-cl1-gray-2 focus-visible:ring-cl1-gray-8 dark:border-cl1-gray-3 dark:text-cl1-gray-7 dark:hover:bg-cl1-gray-7/10 dark:hover:text-cl1-gray-8 dark:focus-visible:ring-cl1-gray-3 m-0 flex shrink-0 cursor-pointer items-center justify-center border-0 border-l border-solid bg-transparent px-3 transition-colors focus-visible:ring-1 focus-visible:outline-none focus-visible:ring-inset astro-qph66ij4"> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" viewBox="0 0 256 256" class="astro-qph66ij4"> <path d="M216,32H88a8,8,0,0,0-8,8V80H40a8,8,0,0,0-8,8V216a8,8,0,0,0,8,8H168a8,8,0,0,0,8-8V176h40a8,8,0,0,0,8-8V40A8,8,0,0,0,216,32ZM160,208H48V96H160Zm48-48H176V88a8,8,0,0,0-8-8H96V48H208Z" class="astro-qph66ij4"></path> </svg> </button> </div> </div> <lc-pm-restore style="display:contents" class="astro-qph66ij4"></lc-pm-restore> </div> <script type="module" src="/_astro/PackageManagers.astro_astro_type_script_index_0_lang.unqpOpS3.js"></script> <ol start="2"> <li>Navigate into your project:</li> </ol> <div class="expressive-code"><link rel="stylesheet" href="/_astro/ec.7rqu9.css"><script type="module" src="/_astro/ec.0vx5m.js"></script><figure class="frame is-terminal not-content"><figcaption class="header"><span class="title"></span><span class="sr-only">Terminal window</span></figcaption><pre data-language="sh"><code><div class="ec-line"><div class="code"><span style="--0:#57C78F;--1:#00783C">cd</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">my-chess-app</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="cd my-chess-app"><div></div></button></div></figure></div> <ol start="3"> <li>Install the required dependencies:</li> </ol> <div class="expressive-code"><figure class="frame is-terminal not-content"><figcaption class="header"><span class="title"></span><span class="sr-only">Terminal window</span></figcaption><pre data-language="sh"><code><div class="ec-line"><div class="code"><span style="--0:#57C78F;--1:#00783C">npm</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">install</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">agents</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">@modelcontextprotocol/sdk</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">chess.js</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">react</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">react-dom</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">react-chessboard</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="npm install agents @modelcontextprotocol/sdk chess.js react react-dom react-chessboard"><div></div></button></div></figure></div> <ol start="4"> <li>Install development dependencies:</li> </ol> <div class="expressive-code"><figure class="frame is-terminal not-content"><figcaption class="header"><span class="title"></span><span class="sr-only">Terminal window</span></figcaption><pre data-language="sh"><code><div class="ec-line"><div class="code"><span style="--0:#57C78F;--1:#00783C">npm</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">install</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">-D</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">@cloudflare/vite-plugin</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">@vitejs/plugin-react</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">vite</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">vite-plugin-singlefile</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">@types/react</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">@types/react-dom</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="npm install -D @cloudflare/vite-plugin @vitejs/plugin-react vite vite-plugin-singlefile @types/react @types/react-dom"><div></div></button></div></figure></div> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="3-configure-your-project">3. Configure your project</h2><a class="anchor-link" href="#3-configure-your-project"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <ol> <li>Update your <code dir="auto">wrangler.jsonc</code> to configure Durable Objects and assets:</li> </ol> <script> (() => { class StarlightTabsRestore extends HTMLElement { connectedCallback() { const starlightTabs = this.closest('starlight-tabs'); if (!(starlightTabs instanceof HTMLElement) || typeof localStorage === 'undefined') return; const syncKey = starlightTabs.dataset.syncKey; if (!syncKey) return; const label = localStorage.getItem(starlight-synced-tabs__${syncKey}); if (!label) return; const tabs = [...starlightTabs?.querySelectorAll('[role="tab"]')]; const tabIndexToRestore = tabs.findIndex( (tab) => tab instanceof HTMLAnchorElement && tab.textContent?.trim() === label ); const panels = starlightTabs?.querySelectorAll(':scope > [role="tabpanel"]'); const newTab = tabs[tabIndexToRestore]; const newPanel = panels[tabIndexToRestore]; if (tabIndexToRestore < 1 || !newTab || !newPanel) return; tabs[0]?.setAttribute('aria-selected', 'false'); tabs[0]?.setAttribute('tabindex', '-1'); panels?.[0]?.setAttribute('hidden', 'true'); newTab.removeAttribute('tabindex'); newTab.setAttribute('aria-selected', 'true'); newPanel.removeAttribute('hidden'); } } customElements.define('starlight-tabs-restore', StarlightTabsRestore); })() </script><starlight-tabs data-sync-key="wranglerConfig" class="astro-6ilsj7c3"> <div class="tablist-wrapper not-content astro-6ilsj7c3"> <ul role="tablist" class="astro-6ilsj7c3"> <li role="presentation" class="tab astro-6ilsj7c3"> <a role="tab" href="#tab-panel-11290" id="tab-11290" aria-selected="true" tabindex="0" class="astro-6ilsj7c3"> <svg aria-hidden="true" class="astro-6ilsj7c3 astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M0.734 13.269L0.562 10.732Q1.938 10.732 2.497 10.087L2.497 10.087Q2.884 9.614 2.884 8.711L2.884 8.711Q2.884 8.324 2.798 7.571Q2.712 6.819 2.712 6.410Q2.712 6.002 2.669 5.185L2.669 5.185Q2.583 4.454 2.583 4.153L2.583 4.153Q2.583 2.089 3.787 1.099Q4.991 0.111 7.184 0.111L7.184 0.111L8.259 0.111L8.259 2.648L7.700 2.648Q6.754 2.648 6.345 3.185Q5.937 3.723 5.937 4.798L5.937 4.798Q5.937 5.056 6.023 5.572L6.023 5.572Q6.109 6.217 6.109 6.561L6.109 6.561Q6.109 6.819 6.152 7.378L6.152 7.378Q6.238 8.152 6.238 8.582L6.238 8.582Q6.238 10.216 5.550 11.033L5.550 11.033Q4.948 11.764 3.658 12.065L3.658 12.065Q4.948 12.409 5.550 13.097L5.550 13.097Q6.238 13.957 6.238 15.548L6.238 15.548Q6.238 16.021 6.152 16.795L6.152 16.795Q6.066 17.354 6.088 17.612Q6.109 17.870 6.023 18.515L6.023 18.515Q5.937 18.988 5.937 19.203L5.937 19.203Q5.937 20.278 6.345 20.815Q6.754 21.353 7.700 21.353L7.700 21.353L8.259 21.353L8.259 23.890L7.184 23.890Q2.712 23.890 2.712 19.848L2.712 19.848Q2.712 18.386 2.862 17.590Q3.013 16.795 3.013 15.290L3.013 15.290Q3.013 13.269 0.734 13.269L0.734 13.269ZM23.438 10.732L23.438 13.011Q21.159 13.011 21.159 15.032L21.159 15.032Q21.159 15.419 21.224 16.171Q21.288 16.924 21.288 17.311L21.288 17.311Q21.417 18.128 21.417 19.590L21.417 19.590Q21.417 23.632 16.859 23.632L16.859 23.632L15.784 23.632L15.784 21.353L16.300 21.353Q17.246 21.353 17.654 20.815Q18.063 20.278 18.063 19.203Q18.063 18.128 17.934 17.569L17.934 17.569Q17.934 17.225 17.848 16.558Q17.762 15.892 17.762 15.548L17.762 15.548Q17.762 13.957 18.450 13.097L18.450 13.097Q19.052 12.409 20.342 12.065L20.342 12.065Q19.052 11.764 18.450 11.033L18.450 11.033Q17.762 10.216 17.762 8.582L17.762 8.582Q17.762 8.152 17.848 7.378L17.848 7.378Q17.934 6.819 17.934 6.561L17.934 6.561Q18.063 5.873 18.063 4.841Q18.063 3.809 17.633 3.293Q17.203 2.777 16.300 2.648L16.300 2.648L15.784 2.648L15.784 0.111L16.859 0.111Q19.009 0.111 20.213 1.099Q21.417 2.089 21.417 4.153L21.417 4.153Q21.417 4.540 21.352 5.292Q21.288 6.045 21.288 6.432L21.288 6.432Q21.159 7.249 21.116 8.711L21.116 8.711Q21.159 9.614 21.503 10.087L21.503 10.087Q22.062 10.732 23.438 10.732L23.438 10.732Z"/></svg> wrangler.jsonc </a> </li><li role="presentation" class="tab astro-6ilsj7c3"> <a role="tab" href="#tab-panel-11291" id="tab-11291" aria-selected="false" tabindex="-1" class="astro-6ilsj7c3"> <svg aria-hidden="true" class="astro-6ilsj7c3 astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="m21.32 9.55-1.89-.63.89-1.78A1 1 0 0 0 20.13 6L18 3.87a1 1 0 0 0-1.15-.19l-1.78.89-.63-1.89A1 1 0 0 0 13.5 2h-3a1 1 0 0 0-.95.68l-.63 1.89-1.78-.89A1 1 0 0 0 6 3.87L3.87 6a1 1 0 0 0-.19 1.15l.89 1.78-1.89.63a1 1 0 0 0-.68.94v3a1 1 0 0 0 .68.95l1.89.63-.89 1.78A1 1 0 0 0 3.87 18L6 20.13a1 1 0 0 0 1.15.19l1.78-.89.63 1.89a1 1 0 0 0 .95.68h3a1 1 0 0 0 .95-.68l.63-1.89 1.78.89a1 1 0 0 0 1.13-.19L20.13 18a1 1 0 0 0 .19-1.15l-.89-1.78 1.89-.63a1 1 0 0 0 .68-.94v-3a1 1 0 0 0-.68-.95ZM20 12.78l-1.2.4A2 2 0 0 0 17.64 16l.57 1.14-1.1 1.1-1.11-.6a2 2 0 0 0-2.79 1.16l-.4 1.2h-1.59l-.4-1.2A2 2 0 0 0 8 17.64l-1.14.57-1.1-1.1.6-1.11a2 2 0 0 0-1.16-2.82l-1.2-.4v-1.56l1.2-.4A2 2 0 0 0 6.36 8l-.57-1.11 1.1-1.1L8 6.36a2 2 0 0 0 2.82-1.16l.4-1.2h1.56l.4 1.2A2 2 0 0 0 16 6.36l1.14-.57 1.1 1.1-.6 1.11a2 2 0 0 0 1.16 2.79l1.2.4v1.59ZM12 8a4 4 0 1 0 0 8 4 4 0 0 0 0-8Zm0 6a2 2 0 1 1 0-4 2 2 0 0 1 0 4Z"/></svg> wrangler.toml </a> </li> </ul> </div> <div id="tab-panel-11290" aria-labelledby="tab-11290" role="tabpanel"> <div class="expressive-code"><link rel="stylesheet" href="/_astro/ec.7rqu9.css"><script type="module" src="/_astro/ec.0vx5m.js"></script><figure class="frame has-title not-content"><figcaption class="header"><span class="title">JSONC</span></figcaption><pre data-language="jsonc"><code><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#C895EA;--1:#7C5B92">name</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"my-chess-app"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#C895EA;--1:#7C5B92">main</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"src/index.ts"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic">// Set this to today's date</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#C895EA;--1:#7C5B92">compatibility_date</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"2026-06-10"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#C895EA;--1:#7C5B92">compatibility_flags</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">[</span><span style="--0:#FDDA68;--1:#A84E00">"nodejs_compat"</span><span style="--0:#89DDFF;--1:#007474">],</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#C895EA;--1:#7C5B92">durable_objects</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#FFCB6B;--1:#7E6435">bindings</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">[</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#F78C6C;--1:#985643">name</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"CHESS"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#F78C6C;--1:#985643">class_name</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"ChessGame"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">],</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#C895EA;--1:#7C5B92">migrations</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">[</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#FFCB6B;--1:#7E6435">tag</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"v1"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#FFCB6B;--1:#7E6435">new_sqlite_classes</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">[</span><span style="--0:#FDDA68;--1:#A84E00">"ChessGame"</span><span style="--0:#89DDFF;--1:#007474">],</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">],</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#C895EA;--1:#7C5B92">assets</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#FFCB6B;--1:#7E6435">directory</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"dist"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#FFCB6B;--1:#7E6435">binding</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"ASSETS"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">}</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="{ "name": "my-chess-app", "main": "src/index.ts", // Set this to today's date "compatibility_date": "2026-06-10", "compatibility_flags": ["nodejs_compat"], "durable_objects": { "bindings": [ { "name": "CHESS", "class_name": "ChessGame", }, ], }, "migrations": [ { "tag": "v1", "new_sqlite_classes": ["ChessGame"], }, ], "assets": { "directory": "dist", "binding": "ASSETS", },}"><div></div></button></div><div class="explain"><button class="explain-button" type="button" data-explain-code="" aria-label="Explain Code"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"></path><path d="M20 3v4"></path><path d="M22 5h-4"></path><path d="M4 17v2"></path><path d="M5 18H3"></path></svg></button></div></figure></div> </div> <div id="tab-panel-11291" aria-labelledby="tab-11291" role="tabpanel" hidden> <div class="expressive-code"><figure class="frame has-title not-content"><figcaption class="header"><span class="title">TOML</span></figcaption><pre data-language="toml"><code><div class="ec-line"><div class="code"><span style="--0:#EEFFFF;--1:#00268F">name</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"my-chess-app"</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EEFFFF;--1:#00268F">main</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"src/index.ts"</span></div></div><div class="ec-line"><div class="code"><span style="--0:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic"># Set this to today's date</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EEFFFF;--1:#00268F">compatibility_date</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"2026-06-10"</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EEFFFF;--1:#00268F">compatibility_flags</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">[</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"nodejs_compat"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">]</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">[[</span><span style="--0:#57C78F;--1:#00783C">durable_objects</span><span style="--0:#EEFFFF;--1:#62676A">.</span><span style="--0:#57C78F;--1:#00783C">bindings</span><span style="--0:#89DDFF;--1:#007474">]]</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EEFFFF;--1:#00268F">name</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"CHESS"</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EEFFFF;--1:#00268F">class_name</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"ChessGame"</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">[[</span><span style="--0:#57C78F;--1:#00783C">migrations</span><span style="--0:#89DDFF;--1:#007474">]]</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EEFFFF;--1:#00268F">tag</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"v1"</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EEFFFF;--1:#00268F">new_sqlite_classes</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">[</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"ChessGame"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">]</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">[</span><span style="--0:#57C78F;--1:#00783C">assets</span><span style="--0:#89DDFF;--1:#007474">]</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EEFFFF;--1:#00268F">directory</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"dist"</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EEFFFF;--1:#00268F">binding</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"ASSETS"</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="name = "my-chess-app"main = "src/index.ts"# Set this to today's datecompatibility_date = "2026-06-10"compatibility_flags = [ "nodejs_compat" ][[durable_objects.bindings]]name = "CHESS"class_name = "ChessGame"[[migrations]]tag = "v1"new_sqlite_classes = [ "ChessGame" ][assets]directory = "dist"binding = "ASSETS""><div></div></button></div><div class="explain"><button class="explain-button" type="button" data-explain-code="" aria-label="Explain Code"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"></path><path d="M20 3v4"></path><path d="M22 5h-4"></path><path d="M4 17v2"></path><path d="M5 18H3"></path></svg></button></div></figure></div> </div> <starlight-tabs-restore class="astro-6ilsj7c3"></starlight-tabs-restore> </starlight-tabs> <script type="module">class r extends HTMLElement{static#e=new Map;#t;#n="starlight-synced-tabs__";constructor(){super();const t=this.querySelector('[role="tablist"]');if(this.tabs=[...t.querySelectorAll('[role="tab"]')],this.panels=[...this.querySelectorAll(':scope > [role="tabpanel"]')],this.#t=this.dataset.syncKey,this.#t){const i=r.#e.get(this.#t)??[];i.push(this),r.#e.set(this.#t,i)}this.tabs.forEach((i,c)=>{i.addEventListener("click",e=>{e.preventDefault();const n=t.querySelector('[aria-selected="true"]');e.currentTarget!==n&&this.switchTab(e.currentTarget,c)}),i.addEventListener("keydown",e=>{const n=this.tabs.indexOf(e.currentTarget),s=e.key==="ArrowLeft"?n-1:e.key==="ArrowRight"?n+1:e.key==="Home"?0:e.key==="End"?this.tabs.length-1:null;s!==null&&this.tabs[s]&&(e.preventDefault(),this.switchTab(this.tabs[s],s))})})}switchTab(t,i,c=!0){if(!t)return;const e=c?this.getBoundingClientRect().top:0;this.tabs.forEach(s=>{s.setAttribute("aria-selected","false"),s.setAttribute("tabindex","-1")}),this.panels.forEach(s=>{s.hidden=!0});const n=this.panels[i];n&&(n.hidden=!1),t.removeAttribute("tabindex"),t.setAttribute("aria-selected","true"),c&&(t.focus(),r.#r(this,t),window.scrollTo({top:window.scrollY+(this.getBoundingClientRect().top-e),behavior:"instant"}))}#i(t){!this.#t||typeof localStorage>"u"||localStorage.setItem(this.#n+this.#t,t)}static#r(t,i){const c=t.#t,e=r.#s(i);if(!c||!e)return;const n=r.#e.get(c);if(n){for(const s of n){if(s===t)continue;const a=s.tabs.findIndex(o=>r.#s(o)===e);a!==-1&&s.switchTab(s.tabs[a],a,!1)}t.#i(e)}}static#s(t){return t.textContent?.trim()}}customElements.define("starlight-tabs",r);</script> <ol start="2"> <li>Create a <code dir="auto">vite.config.ts</code> for building your React UI:</li> </ol> <div class="expressive-code"><figure class="frame has-title not-content"><figcaption class="header"><span class="title">TypeScript</span></figcaption><pre data-language="ts"><code><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">cloudflare</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"@cloudflare/vite-plugin"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--1:#8F1500"><span style="--0:#EE9080">import </span><span style="--0:#D5D7D8">react</span><span style="--0:#EE9080"> from </span></span><span style="--0:#FDDA68;--1:#A84E00">"@vitejs/plugin-react"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">defineConfig</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"vite"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">viteSingleFile</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"vite-plugin-singlefile"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">export</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">default</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">defineConfig</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">plugins</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> [</span><span style="--0:#57C78F;--1:#00783C">react</span><span style="--0:#EEFFFF;--1:#62676A">()</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">cloudflare</span><span style="--0:#EEFFFF;--1:#62676A">()</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">viteSingleFile</span><span style="--0:#EEFFFF;--1:#62676A">()]</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">build</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">minify</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">false</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="import { cloudflare } from "@cloudflare/vite-plugin";import react from "@vitejs/plugin-react";import { defineConfig } from "vite";import { viteSingleFile } from "vite-plugin-singlefile";export default defineConfig({ plugins: [react(), cloudflare(), viteSingleFile()], build: { minify: false, },});"><div></div></button></div><div class="explain"><button class="explain-button" type="button" data-explain-code="" aria-label="Explain Code"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"></path><path d="M20 3v4"></path><path d="M22 5h-4"></path><path d="M4 17v2"></path><path d="M5 18H3"></path></svg></button></div></figure></div> <ol start="3"> <li>Update your <code dir="auto">package.json</code> scripts:</li> </ol> <div class="expressive-code"><figure class="frame not-content"><figcaption class="header"></figcaption><pre data-language="json"><code><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#C895EA;--1:#7C5B92">scripts</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#FFCB6B;--1:#7E6435">dev</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"vite"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#FFCB6B;--1:#7E6435">build</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"vite build"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#FFCB6B;--1:#7E6435">deploy</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"vite build && wrangler deploy"</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">}</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="{ "scripts": { "dev": "vite", "build": "vite build", "deploy": "vite build && wrangler deploy" }}"><div></div></button></div></figure></div> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="4-create-the-chess-game-engine">4. Create the Chess game engine</h2><a class="anchor-link" href="#4-create-the-chess-game-engine"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <ol> <li>Create the game logic using Durable Objects at <code dir="auto">src/chess.tsx</code>:</li> </ol> <div class="expressive-code"><figure class="frame not-content" style="--lnWidth:3ch"><figcaption class="header"></figcaption><pre data-language="tsx"><code><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">Agent</span></span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">callable</span></span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">getCurrentAgent</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"agents"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">Chess</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"chess.js"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">type</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">Color</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"w"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">|</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"b"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">type</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">ConnectionState</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">playerId</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">export</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">type</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">State</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">board</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">players</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--1:#007474"><span style="--0:#EEFFFF"> </span><span style="--0:#89DDFF">{</span><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">w</span><span style="--0:#EE9080;--1:#8F1500">?:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--1:#007474"><span style="--0:#89DDFF">;</span><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">b</span><span style="--0:#EE9080;--1:#8F1500">?:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--1:#007474"><span style="--0:#EEFFFF"> </span><span style="--0:#89DDFF">};</span></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">status</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#FDDA68;--1:#A84E00">"waiting"</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#EE9080;--1:#8F1500">|</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#FDDA68;--1:#A84E00">"active"</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#EE9080;--1:#8F1500">|</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#FDDA68;--1:#A84E00">"mate"</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#EE9080;--1:#8F1500">|</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#FDDA68;--1:#A84E00">"draw"</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#EE9080;--1:#8F1500">|</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#FDDA68;--1:#A84E00">"resigned"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">winner</span><span style="--0:#EE9080;--1:#8F1500">?:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">Color</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">lastSan</span><span style="--0:#EE9080;--1:#8F1500">?:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">export</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">class</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">ChessGame</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">extends</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">Agent</span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#57C78F;--1:#00783C">Env</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">State</span><span style="--0:#89DDFF;--1:#007474">></span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">initialState</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">State</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">board</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">Chess</span><span style="--0:#EEFFFF;--1:#62676A">()</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">fen</span><span style="--0:#EEFFFF;--1:#62676A">()</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">players</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{},</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">status</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"waiting"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">};</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:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">Chess</span><span style="--0:#EEFFFF;--1:#62676A">()</span><span style="--0:#89DDFF;--1:#007474">;</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:#EE9080;--1:#8F1500">constructor</span><span style="--0:#89DDFF;--1:#007474">(</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#B59EE1;--1:#7C008F">ctx</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">DurableObjectState</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">public</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">env</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">Env</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">super</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#D5D7D8;--1:#8F1500">ctx</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">env</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">load</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">board</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</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:#EE9080;--1:#8F1500">private</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">colorOf</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">playerId</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">Color</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">|</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">undefined</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">players</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#EEFFFF;--1:#00268F">players</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">w</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">===</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">playerId</span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"w"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#EEFFFF;--1:#00268F">players</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">b</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">===</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">playerId</span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"b"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">undefined</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</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:#89DDFF;--1:#007474">@</span><span style="--0:#57C78F;--1:#00783C">callable</span><span style="--0:#EEFFFF;--1:#62676A">()</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">join</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">params</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--1:#007474"><span style="--0:#EEFFFF"> </span><span style="--0:#89DDFF">{</span><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">playerId</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--1:#007474"><span style="--0:#89DDFF">;</span><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">preferred</span><span style="--0:#EE9080;--1:#8F1500">?:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">Color</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#EE9080;--1:#8F1500">|</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#FDDA68;--1:#A84E00">"any"</span><span style="--1:#007474"><span style="--0:#EEFFFF"> </span><span style="--0:#89DDFF">})</span></span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">playerId</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">preferred</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"any"</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">params</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">connection</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">getCurrentAgent</span><span style="--0:#EE9080;--1:#32008F">()</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--1:#8F1500"><span style="--0:#EE9080">!</span><span style="--0:#D5D7D8">connection</span></span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#EE9080;--1:#8F1500">throw</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">Error</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#FDDA68;--1:#A84E00">"Not connected"</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</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:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">connection</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">setState</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">playerId</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">s</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#89DDFF;--1:#007474">;</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:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic">// Already seated? Return seat</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">already</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">colorOf</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#D5D7D8;--1:#8F1500">playerId</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#D5D7D8;--1:#8F1500">already</span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> ok</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">true</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> role</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">already</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">as</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">Color</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> state</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">s</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</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:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic">// Choose a seat</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">free</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EE9080;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">Color</span><span style="--0:#EE9080;--1:#007474">[] </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> ([</span><span style="--0:#FDDA68;--1:#A84E00">"w"</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"b"</span><span style="--0:#EE9080;--1:#32008F">] </span><span style="--0:#EE9080;--1:#8F1500">as</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">filter</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">c</span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">!</span><span style="--0:#EEFFFF;--1:#00268F">s</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">players</span><span style="--0:#EE9080;--1:#32008F">[</span><span style="--0:#D5D7D8;--1:#8F1500">c</span><span style="--0:#EE9080;--1:#32008F">])</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#EEFFFF;--1:#00268F">free</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#9D5600">length</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">===</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">0</span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> ok</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">true</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> role</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"spectator"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">as</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> state</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">s</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</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:#EE9080;--1:#8F1500">let</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--1:#8F1500"><span style="--0:#D5D7D8">seat</span><span style="--0:#EE9080">:</span></span><span style="--0:#EE9080;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">Color</span><span style="--0:#EE9080;--1:#007474"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">free</span><span style="--0:#EE9080;--1:#32008F">[</span><span style="--0:#B59EE1;--1:#7C008F">0</span><span style="--0:#EE9080;--1:#32008F">]</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#D5D7D8;--1:#8F1500">preferred</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">===</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"w"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">&&</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EEFFFF;--1:#00268F">free</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">includes</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#FDDA68;--1:#A84E00">"w"</span><span style="--0:#EEFFFF;--1:#62676A">)) </span><span style="--0:#D5D7D8;--1:#8F1500">seat</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"w"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#D5D7D8;--1:#8F1500">preferred</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">===</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"b"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">&&</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EEFFFF;--1:#00268F">free</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">includes</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#FDDA68;--1:#A84E00">"b"</span><span style="--0:#EEFFFF;--1:#62676A">)) </span><span style="--0:#D5D7D8;--1:#8F1500">seat</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"b"</span><span style="--0:#89DDFF;--1:#007474">;</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:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">s</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">players</span><span style="--0:#EEFFFF;--1:#62676A">[</span><span style="--0:#D5D7D8;--1:#8F1500">seat</span><span style="--0:#EEFFFF;--1:#62676A">] </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">playerId</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">s</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">status</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EEFFFF;--1:#00268F">s</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">players</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">w</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">&&</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EEFFFF;--1:#00268F">s</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">players</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">b</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">?</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"active"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"waiting"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">setState</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#D5D7D8;--1:#8F1500">s</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> ok</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">true</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> role</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">seat</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> state</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">s</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</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:#89DDFF;--1:#007474">@</span><span style="--0:#57C78F;--1:#00783C">callable</span><span style="--0:#EEFFFF;--1:#62676A">()</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">move</span><span style="--0:#89DDFF;--1:#007474">(</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#B59EE1;--1:#7C008F">move</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--1:#007474"><span style="--0:#EEFFFF"> </span><span style="--0:#89DDFF">{</span><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">from</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--1:#007474"><span style="--0:#89DDFF">;</span><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">to</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--1:#007474"><span style="--0:#89DDFF">;</span><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">promotion</span><span style="--0:#EE9080;--1:#8F1500">?:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--1:#007474"><span style="--0:#EEFFFF"> </span><span style="--0:#89DDFF">},</span></span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#B59EE1;--1:#7C008F">expectedFen</span><span style="--0:#EE9080;--1:#8F1500">?:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">status</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">===</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"waiting"</span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">ok</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">false</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">reason</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"not-in-game"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">fen</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">fen</span><span style="--0:#EEFFFF;--1:#62676A">()</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">status</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">status</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</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:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">connection</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">getCurrentAgent</span><span style="--0:#EE9080;--1:#32008F">()</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--1:#8F1500"><span style="--0:#EE9080">!</span><span style="--0:#D5D7D8">connection</span></span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#EE9080;--1:#8F1500">throw</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">Error</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#FDDA68;--1:#A84E00">"Not connected"</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">playerId</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">connection</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">as</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">ConnectionState</span><span style="--0:#89DDFF;--1:#007474">;</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:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">seat</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">colorOf</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#D5D7D8;--1:#8F1500">playerId</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--1:#8F1500"><span style="--0:#EE9080">!</span><span style="--0:#D5D7D8">seat</span></span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">ok</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">false</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">reason</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"not-in-game"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">fen</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">fen</span><span style="--0:#EEFFFF;--1:#62676A">()</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">status</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">status</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</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:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#D5D7D8;--1:#8F1500">seat</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">!==</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">turn</span><span style="--0:#EEFFFF;--1:#62676A">()) </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">ok</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">false</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">reason</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"not-your-turn"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">fen</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">fen</span><span style="--0:#EEFFFF;--1:#62676A">()</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">status</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">status</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</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:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic">// Optimistic sync guard</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#D5D7D8;--1:#8F1500">expectedFen</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">&&</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">expectedFen</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">!==</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">fen</span><span style="--0:#EEFFFF;--1:#62676A">()) </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">ok</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">false</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">reason</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"stale"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">fen</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">fen</span><span style="--0:#EEFFFF;--1:#62676A">()</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">status</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">status</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</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:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">res</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">move</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#D5D7D8;--1:#8F1500">move</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--1:#8F1500"><span style="--0:#EE9080">!</span><span style="--0:#D5D7D8">res</span></span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">ok</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">false</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">reason</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"illegal"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">fen</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">fen</span><span style="--0:#EEFFFF;--1:#62676A">()</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">status</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">status</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</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:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">fen</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">fen</span><span style="--0:#EE9080;--1:#32008F">()</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">let</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--1:#8F1500"><span style="--0:#D5D7D8">status</span><span style="--0:#EE9080">:</span></span><span style="--0:#EE9080;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">State</span><span style="--0:#EE9080;--1:#007474">[</span><span style="--0:#FDDA68;--1:#A84E00">"status"</span><span style="--0:#EE9080;--1:#007474">] </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"active"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">isCheckmate</span><span style="--0:#EEFFFF;--1:#62676A">()) </span><span style="--0:#D5D7D8;--1:#8F1500">status</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"mate"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">else</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">isDraw</span><span style="--0:#EEFFFF;--1:#62676A">()) </span><span style="--0:#D5D7D8;--1:#8F1500">status</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"draw"</span><span style="--0:#89DDFF;--1:#007474">;</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:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">setState</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">...</span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">board</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">fen</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">lastSan</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EEFFFF;--1:#00268F">res</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">san</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#D5D7D8;--1:#8F1500">status</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">winner</span><span style="--0:#89DDFF;--1:#007474">:</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#D5D7D8;--1:#8F1500">status</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">===</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"mate"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">?</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">turn</span><span style="--0:#EEFFFF;--1:#62676A">() </span><span style="--0:#EE9080;--1:#8F1500">===</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"w"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">?</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"b"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"w"</span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">undefined</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</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:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> ok</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">true</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">fen</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> san</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EEFFFF;--1:#00268F">res</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">san</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">status</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</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:#89DDFF;--1:#007474">@</span><span style="--0:#57C78F;--1:#00783C">callable</span><span style="--0:#EEFFFF;--1:#62676A">()</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">resign</span><span style="--0:#89DDFF;--1:#007474">()</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">connection</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">getCurrentAgent</span><span style="--0:#EE9080;--1:#32008F">()</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--1:#8F1500"><span style="--0:#EE9080">!</span><span style="--0:#D5D7D8">connection</span></span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#EE9080;--1:#8F1500">throw</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">Error</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#FDDA68;--1:#A84E00">"Not connected"</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">playerId</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">connection</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">as</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">ConnectionState</span><span style="--0:#89DDFF;--1:#007474">;</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:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">seat</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">colorOf</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#D5D7D8;--1:#8F1500">playerId</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--1:#8F1500"><span style="--0:#EE9080">!</span><span style="--0:#D5D7D8">seat</span></span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> ok</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">false</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> reason</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"not-in-game"</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> state</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">};</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:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">winner</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">seat</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">===</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"w"</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">?</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"b"</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"w"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">setState</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">...</span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> status</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"resigned"</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">winner</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> ok</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">true</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> state</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">}</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="import { Agent, callable, getCurrentAgent } from "agents";import { Chess } from "chess.js";type Color = "w" | "b";type ConnectionState = { playerId: string;};export type State = { board: string; players: { w?: string; b?: string }; status: "waiting" | "active" | "mate" | "draw" | "resigned"; winner?: Color; lastSan?: string;};export class ChessGame extends Agent<Env, State> { initialState: State = { board: new Chess().fen(), players: {}, status: "waiting", }; game = new Chess(); constructor( ctx: DurableObjectState, public env: Env, ) { super(ctx, env); this.game.load(this.state.board); } private colorOf(playerId: string): Color | undefined { const { players } = this.state; if (players.w === playerId) return "w"; if (players.b === playerId) return "b"; return undefined; } @callable() join(params: { playerId: string; preferred?: Color | "any" }) { const { playerId, preferred = "any" } = params; const { connection } = getCurrentAgent(); if (!connection) throw new Error("Not connected"); connection.setState({ playerId }); const s = this.state; // Already seated? Return seat const already = this.colorOf(playerId); if (already) { return { ok: true, role: already as Color, state: s }; } // Choose a seat const free: Color[] = (["w", "b"] as const).filter((c) => !s.players[c]); if (free.length === 0) { return { ok: true, role: "spectator" as const, state: s }; } let seat: Color = free[0]; if (preferred === "w" && free.includes("w")) seat = "w"; if (preferred === "b" && free.includes("b")) seat = "b"; s.players[seat] = playerId; s.status = s.players.w && s.players.b ? "active" : "waiting"; this.setState(s); return { ok: true, role: seat, state: s }; } @callable() move( move: { from: string; to: string; promotion?: string }, expectedFen?: string, ) { if (this.state.status === "waiting") { return { ok: false, reason: "not-in-game", fen: this.game.fen(), status: this.state.status, }; } const { connection } = getCurrentAgent(); if (!connection) throw new Error("Not connected"); const { playerId } = connection.state as ConnectionState; const seat = this.colorOf(playerId); if (!seat) { return { ok: false, reason: "not-in-game", fen: this.game.fen(), status: this.state.status, }; } if (seat !== this.game.turn()) { return { ok: false, reason: "not-your-turn", fen: this.game.fen(), status: this.state.status, }; } // Optimistic sync guard if (expectedFen && expectedFen !== this.game.fen()) { return { ok: false, reason: "stale", fen: this.game.fen(), status: this.state.status, }; } const res = this.game.move(move); if (!res) { return { ok: false, reason: "illegal", fen: this.game.fen(), status: this.state.status, }; } const fen = this.game.fen(); let status: State["status"] = "active"; if (this.game.isCheckmate()) status = "mate"; else if (this.game.isDraw()) status = "draw"; this.setState({ ...this.state, board: fen, lastSan: res.san, status, winner: status === "mate" ? (this.game.turn() === "w" ? "b" : "w") : undefined, }); return { ok: true, fen, san: res.san, status }; } @callable() resign() { const { connection } = getCurrentAgent(); if (!connection) throw new Error("Not connected"); const { playerId } = connection.state as ConnectionState; const seat = this.colorOf(playerId); if (!seat) return { ok: false, reason: "not-in-game", state: this.state }; const winner = seat === "w" ? "b" : "w"; this.setState({ ...this.state, status: "resigned", winner }); return { ok: true, state: this.state }; }}"><div></div></button></div><div class="explain"><button class="explain-button" type="button" data-explain-code="" aria-label="Explain Code"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"></path><path d="M20 3v4"></path><path d="M22 5h-4"></path><path d="M4 17v2"></path><path d="M5 18H3"></path></svg></button></div></figure></div> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="5-create-the-mcp-server-and-ui-resource">5. Create the MCP server and UI resource</h2><a class="anchor-link" href="#5-create-the-mcp-server-and-ui-resource"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <ol> <li>Create your main worker at <code dir="auto">src/index.ts</code>:</li> </ol> <div class="expressive-code"><figure class="frame has-title not-content"><figcaption class="header"><span class="title">TypeScript</span></figcaption><pre data-language="ts"><code><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">createMcpHandler</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"agents/mcp"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">routeAgentRequest</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"agents"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">McpServer</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"@modelcontextprotocol/sdk/server/mcp.js"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">env</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"cloudflare:workers"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">getWidgetHtml</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">async</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">host</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EE9080;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080"> </span></span><span style="--0:#EE9080;--1:#8F1500">let</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">html</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">await</span><span style="--0:#EE9080;--1:#32008F"> (</span><span style="--0:#EE9080;--1:#8F1500">await</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">env</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">ASSETS</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">fetch</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#FDDA68;--1:#A84E00">"http://localhost/"</span><span style="--0:#EE9080;--1:#32008F">))</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">text</span><span style="--0:#EE9080;--1:#32008F">()</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#D5D7D8;--1:#8F1500">html</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">html</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">replace</span><span style="--0:#EE9080;--1:#32008F">(</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"<!--RUNTIME_CONFIG-->"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00"><script>window.HOST = </span><span style="--0:#89DDFF;--1:#446E7F">\</span><span style="--0:#89DDFF;--1:#007474">${</span><span style="--0:#D5D7D8;--1:#8F1500">host</span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#89DDFF;--1:#446E7F">\</span><span style="--0:#FDDA68;--1:#A84E00">;</script></span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080"> </span></span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">html</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">function</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">createServer</span><span style="--0:#89DDFF;--1:#007474">()</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">server</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">new</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">McpServer</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EE9080;--1:#32008F"> name</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"Chess"</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> version</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"v1.0.0"</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</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:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic">// Register a UI resource that ChatGPT can render</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">server</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">registerResource</span><span style="--0:#EEFFFF;--1:#62676A">(</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"chess"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"ui://widget/index.html"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">{},</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">async</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">_uri</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">extra</span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">contents</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> [</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">uri</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"ui://widget/index.html"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">mimeType</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"text/html+skybridge"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">text</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">await</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">getWidgetHtml</span><span style="--0:#EEFFFF;--1:#62676A">(</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">extra</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">requestInfo</span><span style="--0:#89DDFF;--1:#007474">?.</span><span style="--0:#EEFFFF;--1:#00268F">headers</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">host</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">as</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">]</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</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:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic">// Register a tool that ChatGPT can call to render the UI</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">server</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">registerTool</span><span style="--0:#EEFFFF;--1:#62676A">(</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"playChess"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">title</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"Renders a chess game menu, ready to start or join a game."</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">annotations</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> readOnlyHint</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">true</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">_meta</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"openai/outputTemplate"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"ui://widget/index.html"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"openai/toolInvocation/invoking"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"Opening chess widget"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"openai/toolInvocation/invoked"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"Chess widget opened"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">async</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">_</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">_extra</span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">content</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> [</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> type</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"text"</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> text</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"Successfully rendered chess game menu"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">]</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</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:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">server</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">export</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">default</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">async</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">fetch</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">req</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">Request</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">env</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">Env</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">ctx</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">ExecutionContext</span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">url</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">new</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">URL</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#EEFFFF;--1:#00268F">req</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">url</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#EEFFFF;--1:#00268F">url</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">pathname</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">startsWith</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#FDDA68;--1:#A84E00">"/mcp"</span><span style="--0:#EEFFFF;--1:#62676A">)) </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic">// Create a new server instance per request</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">server</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">createServer</span><span style="--0:#EE9080;--1:#32008F">()</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">createMcpHandler</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#D5D7D8;--1:#8F1500">server</span><span style="--0:#EEFFFF;--1:#62676A">)(</span><span style="--0:#D5D7D8;--1:#8F1500">req</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">env</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">ctx</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</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:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> (</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#EE9080;--1:#8F1500">await</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">routeAgentRequest</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#D5D7D8;--1:#8F1500">req</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">env</span><span style="--0:#EEFFFF;--1:#62676A">)) </span><span style="--0:#EE9080;--1:#8F1500">??</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">Response</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#FDDA68;--1:#A84E00">"Not found"</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> status</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">404</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EEFFFF;--1:#62676A">)</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">satisfies</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">ExportedHandler</span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#57C78F;--1:#00783C">Env</span><span style="--0:#89DDFF;--1:#007474">>;</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">export</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">ChessGame</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">from</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"./chess"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="import { createMcpHandler } from "agents/mcp";import { routeAgentRequest } from "agents";import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";import { env } from "cloudflare:workers";const getWidgetHtml = async (host: string) => { let html = await (await env.ASSETS.fetch("http://localhost/")).text(); html = html.replace( "<!--RUNTIME_CONFIG-->", `<script>window.HOST = \`${host}\`;</script>`, ); return html;};function createServer() { const server = new McpServer({ name: "Chess", version: "v1.0.0" }); // Register a UI resource that ChatGPT can render server.registerResource( "chess", "ui://widget/index.html", {}, async (_uri, extra) => { return { contents: [ { uri: "ui://widget/index.html", mimeType: "text/html+skybridge", text: await getWidgetHtml( extra.requestInfo?.headers.host as string, ), }, ], }; }, ); // Register a tool that ChatGPT can call to render the UI server.registerTool( "playChess", { title: "Renders a chess game menu, ready to start or join a game.", annotations: { readOnlyHint: true }, _meta: { "openai/outputTemplate": "ui://widget/index.html", "openai/toolInvocation/invoking": "Opening chess widget", "openai/toolInvocation/invoked": "Chess widget opened", }, }, async (_, _extra) => { return { content: [ { type: "text", text: "Successfully rendered chess game menu" }, ], }; }, ); return server;}export default { async fetch(req: Request, env: Env, ctx: ExecutionContext) { const url = new URL(req.url); if (url.pathname.startsWith("/mcp")) { // Create a new server instance per request const server = createServer(); return createMcpHandler(server)(req, env, ctx); } return ( (await routeAgentRequest(req, env)) ?? new Response("Not found", { status: 404 }) ); },} satisfies ExportedHandler<Env>;export { ChessGame } from "./chess";"><div></div></button></div><div class="explain"><button class="explain-button" type="button" data-explain-code="" aria-label="Explain Code"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"></path><path d="M20 3v4"></path><path d="M22 5h-4"></path><path d="M4 17v2"></path><path d="M5 18H3"></path></svg></button></div></figure></div> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="6-build-the-react-ui">6. Build the React UI</h2><a class="anchor-link" href="#6-build-the-react-ui"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <ol> <li>Create the HTML entry point at <code dir="auto">index.html</code>:</li> </ol> <div class="expressive-code"><figure class="frame not-content"><figcaption class="header"></figcaption><pre data-language="html"><code><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474"><!</span><span style="--0:#F38B90;--1:#A54E53">doctype</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#FFCB6B;--0fs:italic;--1:#7E6435;--1fs:italic">html</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#F38B90;--1:#A54E53">html</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#F38B90;--1:#A54E53">head</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic"><!--RUNTIME_CONFIG--></span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474"></</span><span style="--0:#F38B90;--1:#A54E53">head</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#F38B90;--1:#A54E53">body</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#F38B90;--1:#A54E53">div</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#FFCB6B;--0fs:italic;--1:#7E6435;--1fs:italic">id</span><span style="--0:#89DDFF;--1:#007474">=</span><span style="--0:#FDDA68;--1:#A84E00">"root"</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#FFCB6B;--0fs:italic;--1:#7E6435;--1fs:italic">style</span><span style="--0:#89DDFF;--1:#007474">=</span><span style="--0:#FDDA68;--1:#A84E00">"font-family: verdana"</span><span style="--0:#89DDFF;--1:#007474">></</span><span style="--0:#F38B90;--1:#A54E53">div</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#F38B90;--1:#A54E53">script</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#FFCB6B;--0fs:italic;--1:#7E6435;--1fs:italic">type</span><span style="--0:#89DDFF;--1:#007474">=</span><span style="--0:#FDDA68;--1:#A84E00">"module"</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#FFCB6B;--0fs:italic;--1:#7E6435;--1fs:italic">src</span><span style="--0:#89DDFF;--1:#007474">=</span><span style="--0:#FDDA68;--1:#A84E00">"/src/app.tsx"</span><span style="--0:#89DDFF;--1:#007474">></</span><span style="--0:#F38B90;--1:#A54E53">script</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474"></</span><span style="--0:#F38B90;--1:#A54E53">body</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474"></</span><span style="--0:#F38B90;--1:#A54E53">html</span><span style="--0:#89DDFF;--1:#007474">></span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="<!doctype html><html> <head> <!--RUNTIME_CONFIG--> </head> <body> <div id="root" style="font-family: verdana"></div> <script type="module" src="/src/app.tsx"></script> </body></html>"><div></div></button></div><div class="explain"><button class="explain-button" type="button" data-explain-code="" aria-label="Explain Code"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"></path><path d="M20 3v4"></path><path d="M22 5h-4"></path><path d="M4 17v2"></path><path d="M5 18H3"></path></svg></button></div></figure></div> <ol start="2"> <li>Create the React app at <code dir="auto">src/app.tsx</code>:</li> </ol> <div class="expressive-code"><figure class="frame not-content" style="--lnWidth:3ch"><figcaption class="header"></figcaption><pre data-language="tsx"><code><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">useEffect</span></span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">useRef</span></span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">useState</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"react"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">useAgent</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"agents/react"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">createRoot</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"react-dom/client"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">Chess</span></span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--1:#8F1500"><span style="--0:#EE9080"> type </span><span style="--0:#D5D7D8">Square</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"chess.js"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">Chessboard</span></span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--1:#8F1500"><span style="--0:#EE9080"> type </span><span style="--0:#D5D7D8">PieceDropHandlerArgs</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"react-chessboard"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import type </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">State</span><span style="--0:#EE9080"> as </span><span style="--0:#D5D7D8">ServerState</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"./chess"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">function</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">usePlayerId</span><span style="--0:#89DDFF;--1:#007474">()</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">[</span><span style="--0:#EEFFFF;--1:#00268F">pid</span><span style="--0:#89DDFF;--1:#007474">]</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">useState</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">()</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080"> </span></span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">existing</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">localStorage</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">getItem</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#FDDA68;--1:#A84E00">"playerId"</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080"> </span></span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EE9080;--1:#32008F"> (</span><span style="--0:#D5D7D8;--1:#8F1500">existing</span><span style="--0:#EE9080;--1:#32008F">) </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">existing</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080"> </span></span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">id</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">crypto</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">randomUUID</span><span style="--0:#EE9080;--1:#32008F">()</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EEFFFF;--1:#00268F">localStorage</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">setItem</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#FDDA68;--1:#A84E00">"playerId"</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">id</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080"> </span></span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">id</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">pid</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">function</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">App</span><span style="--0:#89DDFF;--1:#007474">()</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">playerId</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">usePlayerId</span><span style="--0:#EE9080;--1:#32008F">()</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">[</span><span style="--0:#EEFFFF;--1:#00268F">gameId</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">setGameId</span><span style="--0:#89DDFF;--1:#007474">]</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">useState</span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">|</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">null</span><span style="--0:#89DDFF;--1:#007474">></span><span style="--0:#EE9080;--1:#32008F">(null)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">[</span><span style="--0:#EEFFFF;--1:#00268F">gameIdInput</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">setGameIdInput</span><span style="--0:#89DDFF;--1:#007474">]</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">useState</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#FDDA68;--1:#A84E00">""</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">[</span><span style="--0:#EEFFFF;--1:#00268F">menuError</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">setMenuError</span><span style="--0:#89DDFF;--1:#007474">]</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">useState</span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">|</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">null</span><span style="--0:#89DDFF;--1:#007474">></span><span style="--0:#EE9080;--1:#32008F">(null)</span><span style="--0:#89DDFF;--1:#007474">;</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:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">gameRef</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">useRef</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#EE9080;--1:#8F1500">new</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">Chess</span><span style="--0:#EE9080;--1:#32008F">())</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">[</span><span style="--0:#EEFFFF;--1:#00268F">fen</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">setFen</span><span style="--0:#89DDFF;--1:#007474">]</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">useState</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#EEFFFF;--1:#00268F">gameRef</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">current</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">fen</span><span style="--0:#EE9080;--1:#32008F">())</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">[</span><span style="--0:#EEFFFF;--1:#00268F">myColor</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">setMyColor</span><span style="--0:#89DDFF;--1:#007474">]</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">useState</span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#FDDA68;--1:#A84E00">"w"</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">|</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"b"</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">|</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"spectator"</span><span style="--0:#89DDFF;--1:#007474">></span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#FDDA68;--1:#A84E00">"spectator"</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">[</span><span style="--0:#EEFFFF;--1:#00268F">pending</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">setPending</span><span style="--0:#89DDFF;--1:#007474">]</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">useState</span><span style="--0:#EE9080;--1:#32008F">(false)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">[</span><span style="--0:#EEFFFF;--1:#00268F">serverState</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">setServerState</span><span style="--0:#89DDFF;--1:#007474">]</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">useState</span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#57C78F;--1:#00783C">ServerState</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">|</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">null</span><span style="--0:#89DDFF;--1:#007474">></span><span style="--0:#EE9080;--1:#32008F">(null)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">[</span><span style="--0:#EEFFFF;--1:#00268F">joined</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">setJoined</span><span style="--0:#89DDFF;--1:#007474">]</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">useState</span><span style="--0:#EE9080;--1:#32008F">(false)</span><span style="--0:#89DDFF;--1:#007474">;</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:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">host</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">window</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">HOST</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">??</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"http://localhost:5173/"</span><span style="--0:#89DDFF;--1:#007474">;</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:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">stub</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">useAgent</span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#57C78F;--1:#00783C">ServerState</span><span style="--0:#89DDFF;--1:#007474">></span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#D5D7D8;--1:#8F1500">host</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">name</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">gameId</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">??</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"__lobby__"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">agent</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"chess"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">onStateUpdate</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">s</span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080"> </span></span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EE9080;--1:#32008F"> (</span><span style="--1:#8F1500"><span style="--0:#EE9080">!</span><span style="--0:#D5D7D8">gameId</span></span><span style="--0:#EE9080;--1:#32008F">) </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EEFFFF;--1:#00268F">gameRef</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">current</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">load</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#EEFFFF;--1:#00268F">s</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">board</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">setFen</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#EEFFFF;--1:#00268F">s</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">board</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">setServerState</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#D5D7D8;--1:#8F1500">s</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</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:#57C78F;--1:#00783C">useEffect</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#89DDFF;--1:#007474">()</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--1:#8F1500"><span style="--0:#EE9080">!</span><span style="--0:#D5D7D8">gameId</span></span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">||</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">joined</span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#89DDFF;--1:#007474">;</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:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#EE9080;--1:#8F1500">async</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">()</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">try</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">res</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">await</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">stub</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">join</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">playerId</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> preferred</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"any"</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#EE9080;--1:#8F1500">!</span><span style="--0:#EEFFFF;--1:#00268F">res</span><span style="--0:#89DDFF;--1:#007474">?.</span><span style="--0:#EEFFFF;--1:#00268F">ok</span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#89DDFF;--1:#007474">;</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:#57C78F;--1:#00783C">setMyColor</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#EEFFFF;--1:#00268F">res</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">role</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">gameRef</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">current</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">load</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#EEFFFF;--1:#00268F">res</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">board</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">setFen</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#EEFFFF;--1:#00268F">res</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">board</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">setServerState</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#EEFFFF;--1:#00268F">res</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">setJoined</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#EE9080;--1:#32008F">true</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">catch</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#D5D7D8;--1:#8F1500">error</span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">console</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">error</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#FDDA68;--1:#A84E00">"Failed to join game"</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">error</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EEFFFF;--1:#62676A">)()</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span><span style="--0:#EEFFFF;--1:#62676A"> [</span><span style="--0:#D5D7D8;--1:#8F1500">playerId</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">gameId</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">stub</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">joined</span><span style="--0:#EEFFFF;--1:#62676A">])</span><span style="--0:#89DDFF;--1:#007474">;</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:#EE9080;--1:#8F1500">async</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">function</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">handleStartNewGame</span><span style="--0:#89DDFF;--1:#007474">()</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">newId</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">crypto</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">randomUUID</span><span style="--0:#EE9080;--1:#32008F">()</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">setGameId</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#D5D7D8;--1:#8F1500">newId</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">setGameIdInput</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#D5D7D8;--1:#8F1500">newId</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">setMenuError</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#EE9080;--1:#32008F">null</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">setJoined</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#EE9080;--1:#32008F">false</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</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:#EE9080;--1:#8F1500">async</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">function</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">handleJoinGame</span><span style="--0:#89DDFF;--1:#007474">()</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">trimmed</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">gameIdInput</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">trim</span><span style="--0:#EE9080;--1:#32008F">()</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--1:#8F1500"><span style="--0:#EE9080">!</span><span style="--0:#D5D7D8">trimmed</span></span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">setMenuError</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#FDDA68;--1:#A84E00">"Enter a game ID to join."</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">setGameId</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#D5D7D8;--1:#8F1500">trimmed</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">setMenuError</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#EE9080;--1:#32008F">null</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">setJoined</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#EE9080;--1:#32008F">false</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</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:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">handleHelpClick</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">()</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EEFFFF;--1:#00268F">window</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">openai</span><span style="--0:#89DDFF;--1:#007474">?.</span><span style="--0:#57C78F;--1:#00783C">sendFollowUpMessage</span><span style="--0:#89DDFF;--1:#007474">?.</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">prompt</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">Help me with my chess game. I am playing as </span><span style="--0:#89DDFF;--1:#007474">${</span><span style="--0:#D5D7D8;--1:#8F1500">myColor</span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#FDDA68;--1:#A84E00"> and the board is: </span><span style="--0:#89DDFF;--1:#007474">${</span><span style="--0:#D5D7D8;--1:#8F1500">fen</span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#FDDA68;--1:#A84E00">. Please only offer written advice.</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">};</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:#EE9080;--1:#8F1500">function</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">onPieceDrop</span><span style="--0:#89DDFF;--1:#007474">({</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">sourceSquare</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">targetSquare</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">PieceDropHandlerArgs</span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--1:#8F1500"><span style="--0:#EE9080">!</span><span style="--0:#D5D7D8">gameId</span></span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">||</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--1:#8F1500"><span style="--0:#EE9080">!</span><span style="--0:#D5D7D8">sourceSquare</span></span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">||</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--1:#8F1500"><span style="--0:#EE9080">!</span><span style="--0:#D5D7D8">targetSquare</span></span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">||</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">pending</span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">false</span><span style="--0:#89DDFF;--1:#007474">;</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:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">gameRef</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">current</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#D5D7D8;--1:#8F1500">myColor</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">===</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"spectator"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">||</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">turn</span><span style="--0:#EEFFFF;--1:#62676A">() </span><span style="--0:#EE9080;--1:#8F1500">!==</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">myColor</span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">false</span><span style="--0:#89DDFF;--1:#007474">;</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:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">piece</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">get</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#D5D7D8;--1:#8F1500">sourceSquare</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">as</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">Square</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--1:#8F1500"><span style="--0:#EE9080">!</span><span style="--0:#D5D7D8">piece</span></span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">||</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EEFFFF;--1:#00268F">piece</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">color</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">!==</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">myColor</span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">false</span><span style="--0:#89DDFF;--1:#007474">;</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:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">prevFen</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">fen</span><span style="--0:#EE9080;--1:#32008F">()</span><span style="--0:#89DDFF;--1:#007474">;</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:#EE9080;--1:#8F1500">try</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">local</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">move</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">from</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">sourceSquare</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">to</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">targetSquare</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">promotion</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"q"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--1:#8F1500"><span style="--0:#EE9080">!</span><span style="--0:#D5D7D8">local</span></span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">false</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">catch</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">false</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</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:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">nextFen</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">fen</span><span style="--0:#EE9080;--1:#32008F">()</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">setFen</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#D5D7D8;--1:#8F1500">nextFen</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">setPending</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#EE9080;--1:#32008F">true</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</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:#D5D7D8;--1:#8F1500">stub</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">move</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> from</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">sourceSquare</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> to</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">targetSquare</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> promotion</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"q"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">},</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">prevFen</span><span style="--0:#EEFFFF;--1:#62676A">)</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">then</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">r</span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#EE9080;--1:#8F1500">!</span><span style="--0:#EEFFFF;--1:#00268F">r</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">ok</span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">load</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#EEFFFF;--1:#00268F">r</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">fen</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">setFen</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#EEFFFF;--1:#00268F">r</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">fen</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EEFFFF;--1:#62676A">)</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">finally</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#89DDFF;--1:#007474">()</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">setPending</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#EE9080;--1:#32008F">false</span><span style="--0:#EEFFFF;--1:#62676A">))</span><span style="--0:#89DDFF;--1:#007474">;</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:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">true</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</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:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> (</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#F38B90;--1:#A54E53">div</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#C895EA;--1:#7C5B92">style</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{{ padding: </span><span style="--0:#FDDA68;--1:#A84E00">"20px"</span><span style="--0:#89DDFF;--1:#007474">, background: </span><span style="--0:#FDDA68;--1:#A84E00">"#f8fafc"</span><span style="--0:#89DDFF;--1:#007474">, minHeight: </span><span style="--0:#FDDA68;--1:#A84E00">"100vh"</span><span style="--0:#89DDFF;--1:#007474"> }}></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080">!</span><span style="--0:#D5D7D8">gameId</span></span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#EE9080;--1:#8F1500">?</span><span style="--0:#89DDFF;--1:#007474"> (</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#F38B90;--1:#A54E53">div</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#C895EA;--1:#7C5B92">style</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">maxWidth: </span><span style="--0:#FDDA68;--1:#A84E00">"420px"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">margin: </span><span style="--0:#FDDA68;--1:#A84E00">"0 auto"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">background: </span><span style="--0:#FDDA68;--1:#A84E00">"#fff"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">borderRadius: </span><span style="--0:#FDDA68;--1:#A84E00">"16px"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">padding: </span><span style="--0:#FDDA68;--1:#A84E00">"24px"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">}}</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#F38B90;--1:#A54E53">h1</span><span style="--0:#89DDFF;--1:#007474">>Ready to play?</</span><span style="--0:#F38B90;--1:#A54E53">h1</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#F38B90;--1:#A54E53">p</span><span style="--0:#89DDFF;--1:#007474">>Start a new match or join an existing game.</</span><span style="--0:#F38B90;--1:#A54E53">p</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#F38B90;--1:#A54E53">button</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#C895EA;--1:#7C5B92">onClick</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#D5D7D8;--1:#8F1500">handleStartNewGame</span><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#C895EA;--1:#7C5B92">style</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">padding: </span><span style="--0:#FDDA68;--1:#A84E00">"12px"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">background: </span><span style="--0:#FDDA68;--1:#A84E00">"#2563eb"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">color: </span><span style="--0:#FDDA68;--1:#A84E00">"#fff"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">border: </span><span style="--0:#FDDA68;--1:#A84E00">"none"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">borderRadius: </span><span style="--0:#FDDA68;--1:#A84E00">"8px"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">cursor: </span><span style="--0:#FDDA68;--1:#A84E00">"pointer"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">width: </span><span style="--0:#FDDA68;--1:#A84E00">"100%"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">}}</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">Start a new game</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"></</span><span style="--0:#F38B90;--1:#A54E53">button</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#F38B90;--1:#A54E53">div</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#C895EA;--1:#7C5B92">style</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{{ marginTop: </span><span style="--0:#FDDA68;--1:#A84E00">"16px"</span><span style="--0:#89DDFF;--1:#007474"> }}></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#F38B90;--1:#A54E53">input</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#C895EA;--1:#7C5B92">placeholder</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#FDDA68;--1:#A84E00">"Paste a game ID"</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#C895EA;--1:#7C5B92">value</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#D5D7D8;--1:#8F1500">gameIdInput</span><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#C895EA;--1:#7C5B92">onChange</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{(</span><span style="--0:#B59EE1;--1:#7C008F">e</span><span style="--0:#89DDFF;--1:#007474">) </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">setGameIdInput</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#EEFFFF;--1:#00268F">e</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">target</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">value</span><span style="--0:#89DDFF;--1:#007474">)}</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#C895EA;--1:#7C5B92">style</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">width: </span><span style="--0:#FDDA68;--1:#A84E00">"100%"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">padding: </span><span style="--0:#FDDA68;--1:#A84E00">"10px"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">borderRadius: </span><span style="--0:#FDDA68;--1:#A84E00">"8px"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">border: </span><span style="--0:#FDDA68;--1:#A84E00">"1px solid #ccc"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">}}</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">/></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#F38B90;--1:#A54E53">button</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#C895EA;--1:#7C5B92">onClick</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#D5D7D8;--1:#8F1500">handleJoinGame</span><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#C895EA;--1:#7C5B92">style</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">marginTop: </span><span style="--0:#FDDA68;--1:#A84E00">"8px"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">padding: </span><span style="--0:#FDDA68;--1:#A84E00">"10px"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">background: </span><span style="--0:#FDDA68;--1:#A84E00">"#0f172a"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">color: </span><span style="--0:#FDDA68;--1:#A84E00">"#fff"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">border: </span><span style="--0:#FDDA68;--1:#A84E00">"none"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">borderRadius: </span><span style="--0:#FDDA68;--1:#A84E00">"8px"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">cursor: </span><span style="--0:#FDDA68;--1:#A84E00">"pointer"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">width: </span><span style="--0:#FDDA68;--1:#A84E00">"100%"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">}}</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">Join</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"></</span><span style="--0:#F38B90;--1:#A54E53">button</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#D5D7D8;--1:#8F1500">menuError</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#EE9080;--1:#8F1500">&&</span><span style="--0:#89DDFF;--1:#007474"> (</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#F38B90;--1:#A54E53">p</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#C895EA;--1:#7C5B92">style</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{{ color: </span><span style="--0:#FDDA68;--1:#A84E00">"red"</span><span style="--0:#89DDFF;--1:#007474">, fontSize: </span><span style="--0:#FDDA68;--1:#A84E00">"0.85rem"</span><span style="--0:#89DDFF;--1:#007474"> }}>{</span><span style="--0:#D5D7D8;--1:#8F1500">menuError</span><span style="--0:#89DDFF;--1:#007474">}</</span><span style="--0:#F38B90;--1:#A54E53">p</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">)}</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"></</span><span style="--0:#F38B90;--1:#A54E53">div</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"></</span><span style="--0:#F38B90;--1:#A54E53">div</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">) </span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#89DDFF;--1:#007474"> (</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#F38B90;--1:#A54E53">div</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#C895EA;--1:#7C5B92">style</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{{ maxWidth: </span><span style="--0:#FDDA68;--1:#A84E00">"600px"</span><span style="--0:#89DDFF;--1:#007474">, margin: </span><span style="--0:#FDDA68;--1:#A84E00">"0 auto"</span><span style="--0:#89DDFF;--1:#007474"> }}></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#F38B90;--1:#A54E53">div</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#C895EA;--1:#7C5B92">style</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">background: </span><span style="--0:#FDDA68;--1:#A84E00">"#fff"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">padding: </span><span style="--0:#FDDA68;--1:#A84E00">"16px"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">borderRadius: </span><span style="--0:#FDDA68;--1:#A84E00">"16px"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">marginBottom: </span><span style="--0:#FDDA68;--1:#A84E00">"16px"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">}}</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#F38B90;--1:#A54E53">h2</span><span style="--0:#89DDFF;--1:#007474">>Game {</span><span style="--0:#D5D7D8;--1:#8F1500">gameId</span><span style="--0:#89DDFF;--1:#007474">}</</span><span style="--0:#F38B90;--1:#A54E53">h2</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#F38B90;--1:#A54E53">p</span><span style="--0:#89DDFF;--1:#007474">>Status: {</span><span style="--0:#EEFFFF;--1:#00268F">serverState</span><span style="--0:#89DDFF;--1:#007474">?.</span><span style="--0:#EEFFFF;--1:#00268F">status</span><span style="--0:#89DDFF;--1:#007474">}</</span><span style="--0:#F38B90;--1:#A54E53">p</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#F38B90;--1:#A54E53">button</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#C895EA;--1:#7C5B92">onClick</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#D5D7D8;--1:#8F1500">handleHelpClick</span><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#C895EA;--1:#7C5B92">style</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">padding: </span><span style="--0:#FDDA68;--1:#A84E00">"10px"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">background: </span><span style="--0:#FDDA68;--1:#A84E00">"#2563eb"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">color: </span><span style="--0:#FDDA68;--1:#A84E00">"#fff"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">border: </span><span style="--0:#FDDA68;--1:#A84E00">"none"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">borderRadius: </span><span style="--0:#FDDA68;--1:#A84E00">"8px"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">cursor: </span><span style="--0:#FDDA68;--1:#A84E00">"pointer"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">}}</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">Ask for help</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"></</span><span style="--0:#F38B90;--1:#A54E53">button</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"></</span><span style="--0:#F38B90;--1:#A54E53">div</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#F38B90;--1:#A54E53">div</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#C895EA;--1:#7C5B92">style</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">background: </span><span style="--0:#FDDA68;--1:#A84E00">"#fff"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">padding: </span><span style="--0:#FDDA68;--1:#A84E00">"16px"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">borderRadius: </span><span style="--0:#FDDA68;--1:#A84E00">"16px"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">}}</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#57C78F;--1:#00783C">Chessboard</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#C895EA;--1:#7C5B92">position</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#D5D7D8;--1:#8F1500">fen</span><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#C895EA;--1:#7C5B92">onPieceDrop</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#D5D7D8;--1:#8F1500">onPieceDrop</span><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#C895EA;--1:#7C5B92">boardOrientation</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#D5D7D8;--1:#8F1500">myColor</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#EE9080;--1:#8F1500">===</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#FDDA68;--1:#A84E00">"b"</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#EE9080;--1:#8F1500">?</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#FDDA68;--1:#A84E00">"black"</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#FDDA68;--1:#A84E00">"white"</span><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">/></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"></</span><span style="--0:#F38B90;--1:#A54E53">div</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"></</span><span style="--0:#F38B90;--1:#A54E53">div</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">)}</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474"></</span><span style="--0:#F38B90;--1:#A54E53">div</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">root</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">createRoot</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#EEFFFF;--1:#00268F">document</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">getElementById</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#FDDA68;--1:#A84E00">"root"</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#EE9080;--1:#8F1500">!</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EEFFFF;--1:#00268F">root</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">render</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#57C78F;--1:#00783C">App</span><span style="--0:#89DDFF;--1:#007474"> /></span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="import { useEffect, useRef, useState } from "react";import { useAgent } from "agents/react";import { createRoot } from "react-dom/client";import { Chess, type Square } from "chess.js";import { Chessboard, type PieceDropHandlerArgs } from "react-chessboard";import type { State as ServerState } from "./chess";function usePlayerId() { const [pid] = useState(() => { const existing = localStorage.getItem("playerId"); if (existing) return existing; const id = crypto.randomUUID(); localStorage.setItem("playerId", id); return id; }); return pid;}function App() { const playerId = usePlayerId(); const [gameId, setGameId] = useState<string | null>(null); const [gameIdInput, setGameIdInput] = useState(""); const [menuError, setMenuError] = useState<string | null>(null); const gameRef = useRef(new Chess()); const [fen, setFen] = useState(gameRef.current.fen()); const [myColor, setMyColor] = useState<"w" | "b" | "spectator">("spectator"); const [pending, setPending] = useState(false); const [serverState, setServerState] = useState<ServerState | null>(null); const [joined, setJoined] = useState(false); const host = window.HOST ?? "http://localhost:5173/"; const { stub } = useAgent<ServerState>({ host, name: gameId ?? "__lobby__", agent: "chess", onStateUpdate: (s) => { if (!gameId) return; gameRef.current.load(s.board); setFen(s.board); setServerState(s); }, }); useEffect(() => { if (!gameId || joined) return; (async () => { try { const res = await stub.join({ playerId, preferred: "any" }); if (!res?.ok) return; setMyColor(res.role); gameRef.current.load(res.state.board); setFen(res.state.board); setServerState(res.state); setJoined(true); } catch (error) { console.error("Failed to join game", error); } })(); }, [playerId, gameId, stub, joined]); async function handleStartNewGame() { const newId = crypto.randomUUID(); setGameId(newId); setGameIdInput(newId); setMenuError(null); setJoined(false); } async function handleJoinGame() { const trimmed = gameIdInput.trim(); if (!trimmed) { setMenuError("Enter a game ID to join."); return; } setGameId(trimmed); setMenuError(null); setJoined(false); } const handleHelpClick = () => { window.openai?.sendFollowUpMessage?.({ prompt: `Help me with my chess game. I am playing as ${myColor} and the board is: ${fen}. Please only offer written advice.`, }); }; function onPieceDrop({ sourceSquare, targetSquare }: PieceDropHandlerArgs) { if (!gameId || !sourceSquare || !targetSquare || pending) return false; const game = gameRef.current; if (myColor === "spectator" || game.turn() !== myColor) return false; const piece = game.get(sourceSquare as Square); if (!piece || piece.color !== myColor) return false; const prevFen = game.fen(); try { const local = game.move({ from: sourceSquare, to: targetSquare, promotion: "q", }); if (!local) return false; } catch { return false; } const nextFen = game.fen(); setFen(nextFen); setPending(true); stub .move({ from: sourceSquare, to: targetSquare, promotion: "q" }, prevFen) .then((r) => { if (!r.ok) { game.load(r.fen); setFen(r.fen); } }) .finally(() => setPending(false)); return true; } return ( <div style={{ padding: "20px", background: "#f8fafc", minHeight: "100vh" }}> {!gameId ? ( <div style={{ maxWidth: "420px", margin: "0 auto", background: "#fff", borderRadius: "16px", padding: "24px", }} > <h1>Ready to play?</h1> <p>Start a new match or join an existing game.</p> <button onClick={handleStartNewGame} style={{ padding: "12px", background: "#2563eb", color: "#fff", border: "none", borderRadius: "8px", cursor: "pointer", width: "100%", }} > Start a new game </button> <div style={{ marginTop: "16px" }}> <input placeholder="Paste a game ID" value={gameIdInput} onChange={(e) => setGameIdInput(e.target.value)} style={{ width: "100%", padding: "10px", borderRadius: "8px", border: "1px solid #ccc", }} /> <button onClick={handleJoinGame} style={{ marginTop: "8px", padding: "10px", background: "#0f172a", color: "#fff", border: "none", borderRadius: "8px", cursor: "pointer", width: "100%", }} > Join </button> {menuError && ( <p style={{ color: "red", fontSize: "0.85rem" }}>{menuError}</p> )} </div> </div> ) : ( <div style={{ maxWidth: "600px", margin: "0 auto" }}> <div style={{ background: "#fff", padding: "16px", borderRadius: "16px", marginBottom: "16px", }} > <h2>Game {gameId}</h2> <p>Status: {serverState?.status}</p> <button onClick={handleHelpClick} style={{ padding: "10px", background: "#2563eb", color: "#fff", border: "none", borderRadius: "8px", cursor: "pointer", }} > Ask for help </button> </div> <div style={{ background: "#fff", padding: "16px", borderRadius: "16px", }} > <Chessboard position={fen} onPieceDrop={onPieceDrop} boardOrientation={myColor === "b" ? "black" : "white"} /> </div> </div> )} </div> );}const root = createRoot(document.getElementById("root")!);root.render(<App />);"><div></div></button></div><div class="explain"><button class="explain-button" type="button" data-explain-code="" aria-label="Explain Code"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"></path><path d="M20 3v4"></path><path d="M22 5h-4"></path><path d="M4 17v2"></path><path d="M5 18H3"></path></svg></button></div></figure></div> <aside aria-label="Note" class="starlight-aside starlight-aside--note"><p class="starlight-aside__title" aria-hidden="true"><svg viewBox="0 0 24 24" width="16" height="16" fill="currentColor" class="starlight-aside__icon"><path d="M12 11C11.7348 11 11.4804 11.1054 11.2929 11.2929C11.1054 11.4804 11 11.7348 11 12V16C11 16.2652 11.1054 16.5196 11.2929 16.7071C11.4804 16.8946 11.7348 17 12 17C12.2652 17 12.5196 16.8946 12.7071 16.7071C12.8946 16.5196 13 16.2652 13 16V12C13 11.7348 12.8946 11.4804 12.7071 11.2929C12.5196 11.1054 12.2652 11 12 11ZM12.38 7.08C12.1365 6.97998 11.8635 6.97998 11.62 7.08C11.4973 7.12759 11.3851 7.19896 11.29 7.29C11.2017 7.3872 11.1306 7.49882 11.08 7.62C11.024 7.73868 10.9966 7.86882 11 8C10.9992 8.13161 11.0245 8.26207 11.0742 8.38391C11.124 8.50574 11.1973 8.61656 11.29 8.71C11.3872 8.79833 11.4988 8.86936 11.62 8.92C11.7715 8.98224 11.936 9.00632 12.099 8.99011C12.2619 8.97391 12.4184 8.91792 12.5547 8.82707C12.691 8.73622 12.8029 8.61328 12.8805 8.46907C12.9582 8.32486 12.9992 8.16378 13 8C12.9963 7.73523 12.8927 7.48163 12.71 7.29C12.6149 7.19896 12.5028 7.12759 12.38 7.08ZM12 2C10.0222 2 8.08879 2.58649 6.4443 3.6853C4.79981 4.78412 3.51809 6.3459 2.76121 8.17317C2.00433 10.0004 1.8063 12.0111 2.19215 13.9509C2.578 15.8907 3.53041 17.6725 4.92894 19.0711C6.32746 20.4696 8.10929 21.422 10.0491 21.8079C11.9889 22.1937 13.9996 21.9957 15.8268 21.2388C17.6541 20.4819 19.2159 19.2002 20.3147 17.5557C21.4135 15.9112 22 13.9778 22 12C22 10.6868 21.7413 9.38642 21.2388 8.17317C20.7363 6.95991 19.9997 5.85752 19.0711 4.92893C18.1425 4.00035 17.0401 3.26375 15.8268 2.7612C14.6136 2.25866 13.3132 2 12 2ZM12 20C10.4178 20 8.87104 19.5308 7.55544 18.6518C6.23985 17.7727 5.21447 16.5233 4.60897 15.0615C4.00347 13.5997 3.84504 11.9911 4.15372 10.4393C4.4624 8.88743 5.22433 7.46197 6.34315 6.34315C7.46197 5.22433 8.88743 4.4624 10.4393 4.15372C11.9911 3.84504 13.5997 4.00346 15.0615 4.60896C16.5233 5.21447 17.7727 6.23984 18.6518 7.55544C19.5308 8.87103 20 10.4177 20 12C20 14.1217 19.1572 16.1566 17.6569 17.6569C16.1566 19.1571 14.1217 20 12 20Z"></path></svg>Note</p><div class="starlight-aside__content"><p>This is a simplified version of the UI. For the complete implementation with player slots, better styling, and game state management, check out the <a href="https://github.com/cloudflare/agents/tree/main/openai-sdk/chess-app/src/app.tsx" target="_blank" rel="noopener">full example on GitHub<span class="external-link"> ↗</span></a>.</p></div></aside> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="7-build-and-deploy">7. Build and deploy</h2><a class="anchor-link" href="#7-build-and-deploy"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <ol> <li>Build your React UI:</li> </ol> <div class="expressive-code"><figure class="frame is-terminal not-content"><figcaption class="header"><span class="title"></span><span class="sr-only">Terminal window</span></figcaption><pre data-language="sh"><code><div class="ec-line"><div class="code"><span style="--0:#57C78F;--1:#00783C">npm</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">run</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">build</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="npm run build"><div></div></button></div></figure></div> <p>This compiles your React app into a single HTML file in the <code dir="auto">dist</code> directory.</p> <ol start="2"> <li>Deploy to Cloudflare:</li> </ol> <div class="expressive-code"><figure class="frame is-terminal not-content"><figcaption class="header"><span class="title"></span><span class="sr-only">Terminal window</span></figcaption><pre data-language="sh"><code><div class="ec-line"><div class="code"><span style="--0:#57C78F;--1:#00783C">npx</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">wrangler</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">deploy</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="npx wrangler deploy"><div></div></button></div></figure></div> <p>After deployment, you will see your app URL:</p> <div class="expressive-code"><figure class="frame not-content"><figcaption class="header"></figcaption><pre data-language="plaintext"><code><div class="ec-line"><div class="code"><span style="--0:#eeffff;--1:#62676a">https://my-chess-app.YOUR_SUBDOMAIN.workers.dev</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="https://my-chess-app.YOUR_SUBDOMAIN.workers.dev"><div></div></button></div></figure></div> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="8-connect-to-chatgpt">8. Connect to ChatGPT</h2><a class="anchor-link" href="#8-connect-to-chatgpt"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <p>Now connect your deployed app to ChatGPT:</p> <ol> <li>Open <a href="https://chat.openai.com/" target="_blank" rel="noopener">ChatGPT<span class="external-link"> ↗</span></a>.</li> <li>Go to <strong>Settings</strong> > <strong>Apps & Connectors</strong> > <strong>Create</strong></li> <li>Give your app a <strong>name</strong>, and optionally a <strong>description</strong> and <strong>icon</strong>.</li> <li>Enter your MCP endpoint: <code dir="auto">https://my-chess-app.YOUR_SUBDOMAIN.workers.dev/mcp</code>.</li> <li>Select <strong>"No authentication"</strong>.</li> <li>Select <strong>"Create"</strong>.</li> </ol> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="9-play-chess-in-chatgpt">9. Play chess in ChatGPT</h2><a class="anchor-link" href="#9-play-chess-in-chatgpt"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <p>Try it out:</p> <ol> <li>In your ChatGPT conversation, type: "Let's play chess".</li> <li>ChatGPT will call the <code dir="auto">playChess</code> tool and render your interactive chess widget.</li> <li>Select <strong>"Start a new game"</strong> to create a game.</li> <li>Share the game ID with a friend who can join via their own ChatGPT conversation.</li> <li>Make moves by dragging pieces on the board.</li> <li>Select <strong>"Ask for help"</strong> to get strategic advice from ChatGPT</li> </ol> <aside aria-label="Note" class="starlight-aside starlight-aside--note"><p class="starlight-aside__title" aria-hidden="true"><svg viewBox="0 0 24 24" width="16" height="16" fill="currentColor" class="starlight-aside__icon"><path d="M12 11C11.7348 11 11.4804 11.1054 11.2929 11.2929C11.1054 11.4804 11 11.7348 11 12V16C11 16.2652 11.1054 16.5196 11.2929 16.7071C11.4804 16.8946 11.7348 17 12 17C12.2652 17 12.5196 16.8946 12.7071 16.7071C12.8946 16.5196 13 16.2652 13 16V12C13 11.7348 12.8946 11.4804 12.7071 11.2929C12.5196 11.1054 12.2652 11 12 11ZM12.38 7.08C12.1365 6.97998 11.8635 6.97998 11.62 7.08C11.4973 7.12759 11.3851 7.19896 11.29 7.29C11.2017 7.3872 11.1306 7.49882 11.08 7.62C11.024 7.73868 10.9966 7.86882 11 8C10.9992 8.13161 11.0245 8.26207 11.0742 8.38391C11.124 8.50574 11.1973 8.61656 11.29 8.71C11.3872 8.79833 11.4988 8.86936 11.62 8.92C11.7715 8.98224 11.936 9.00632 12.099 8.99011C12.2619 8.97391 12.4184 8.91792 12.5547 8.82707C12.691 8.73622 12.8029 8.61328 12.8805 8.46907C12.9582 8.32486 12.9992 8.16378 13 8C12.9963 7.73523 12.8927 7.48163 12.71 7.29C12.6149 7.19896 12.5028 7.12759 12.38 7.08ZM12 2C10.0222 2 8.08879 2.58649 6.4443 3.6853C4.79981 4.78412 3.51809 6.3459 2.76121 8.17317C2.00433 10.0004 1.8063 12.0111 2.19215 13.9509C2.578 15.8907 3.53041 17.6725 4.92894 19.0711C6.32746 20.4696 8.10929 21.422 10.0491 21.8079C11.9889 22.1937 13.9996 21.9957 15.8268 21.2388C17.6541 20.4819 19.2159 19.2002 20.3147 17.5557C21.4135 15.9112 22 13.9778 22 12C22 10.6868 21.7413 9.38642 21.2388 8.17317C20.7363 6.95991 19.9997 5.85752 19.0711 4.92893C18.1425 4.00035 17.0401 3.26375 15.8268 2.7612C14.6136 2.25866 13.3132 2 12 2ZM12 20C10.4178 20 8.87104 19.5308 7.55544 18.6518C6.23985 17.7727 5.21447 16.5233 4.60897 15.0615C4.00347 13.5997 3.84504 11.9911 4.15372 10.4393C4.4624 8.88743 5.22433 7.46197 6.34315 6.34315C7.46197 5.22433 8.88743 4.4624 10.4393 4.15372C11.9911 3.84504 13.5997 4.00346 15.0615 4.60896C16.5233 5.21447 17.7727 6.23984 18.6518 7.55544C19.5308 8.87103 20 10.4177 20 12C20 14.1217 19.1572 16.1566 17.6569 17.6569C16.1566 19.1571 14.1217 20 12 20Z"></path></svg>Note</p><div class="starlight-aside__content"><p>You might need to manually select the connector in the prompt box the first time you use it. Select <strong>"+"</strong> > <strong>"More"</strong> > <strong>[App name]</strong>.</p></div></aside> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="key-concepts">Key concepts</h2><a class="anchor-link" href="#key-concepts"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <div tabindex="-1" class="heading-wrapper level-h3"><h3 id="mcp-server">MCP Server</h3><a class="anchor-link" href="#mcp-server"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <p>The Model Context Protocol (MCP) server defines tools and resources that ChatGPT can access. Note that we create a new server instance per request to prevent cross-client response leakage:</p> <div class="expressive-code"><figure class="frame has-title not-content"><figcaption class="header"><span class="title">TypeScript</span></figcaption><pre data-language="ts"><code><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">function</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">createServer</span><span style="--0:#89DDFF;--1:#007474">()</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">server</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">new</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">McpServer</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EE9080;--1:#32008F"> name</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"Chess"</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> version</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"v1.0.0"</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</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:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic">// Register a UI resource that ChatGPT can render</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">server</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">registerResource</span><span style="--0:#EEFFFF;--1:#62676A">(</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"chess"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"ui://widget/index.html"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">{},</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">async</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">_uri</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">extra</span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">contents</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> [</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">uri</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"ui://widget/index.html"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">mimeType</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"text/html+skybridge"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">text</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">await</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">getWidgetHtml</span><span style="--0:#EEFFFF;--1:#62676A">(</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">extra</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">requestInfo</span><span style="--0:#89DDFF;--1:#007474">?.</span><span style="--0:#EEFFFF;--1:#00268F">headers</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">host</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">as</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">]</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</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:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic">// Register a tool that ChatGPT can call to render the UI</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">server</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">registerTool</span><span style="--0:#EEFFFF;--1:#62676A">(</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"playChess"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">title</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"Renders a chess game menu, ready to start or join a game."</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">annotations</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> readOnlyHint</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">true</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">_meta</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"openai/outputTemplate"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"ui://widget/index.html"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"openai/toolInvocation/invoking"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"Opening chess widget"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"openai/toolInvocation/invoked"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"Chess widget opened"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">async</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">_</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">_extra</span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">content</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> [</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> type</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"text"</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> text</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"Successfully rendered chess game menu"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">]</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</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:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">server</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">}</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="function createServer() { const server = new McpServer({ name: "Chess", version: "v1.0.0" }); // Register a UI resource that ChatGPT can render server.registerResource( "chess", "ui://widget/index.html", {}, async (_uri, extra) => { return { contents: [ { uri: "ui://widget/index.html", mimeType: "text/html+skybridge", text: await getWidgetHtml( extra.requestInfo?.headers.host as string, ), }, ], }; }, ); // Register a tool that ChatGPT can call to render the UI server.registerTool( "playChess", { title: "Renders a chess game menu, ready to start or join a game.", annotations: { readOnlyHint: true }, _meta: { "openai/outputTemplate": "ui://widget/index.html", "openai/toolInvocation/invoking": "Opening chess widget", "openai/toolInvocation/invoked": "Chess widget opened", }, }, async (_, _extra) => { return { content: [ { type: "text", text: "Successfully rendered chess game menu" }, ], }; }, ); return server;}"><div></div></button></div><div class="explain"><button class="explain-button" type="button" data-explain-code="" aria-label="Explain Code"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"></path><path d="M20 3v4"></path><path d="M22 5h-4"></path><path d="M4 17v2"></path><path d="M5 18H3"></path></svg></button></div></figure></div> <div tabindex="-1" class="heading-wrapper level-h3"><h3 id="game-engine-with-agents">Game Engine with Agents</h3><a class="anchor-link" href="#game-engine-with-agents"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <p>The <code dir="auto">ChessGame</code> class extends <code dir="auto">Agent</code> to create a stateful game engine:</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:#EE9080;--1:#8F1500">export</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">class</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">ChessGame</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">extends</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">Agent</span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#57C78F;--1:#00783C">Env</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">State</span><span style="--0:#89DDFF;--1:#007474">></span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">initialState</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">State</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">board</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">Chess</span><span style="--0:#EEFFFF;--1:#62676A">()</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">fen</span><span style="--0:#EEFFFF;--1:#62676A">()</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">players</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{},</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">status</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"waiting"</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">};</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:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">Chess</span><span style="--0:#EEFFFF;--1:#62676A">()</span><span style="--0:#89DDFF;--1:#007474">;</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:#EE9080;--1:#8F1500">constructor</span><span style="--0:#89DDFF;--1:#007474">(</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#B59EE1;--1:#7C008F">ctx</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">DurableObjectState</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">public</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">env</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">Env</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">super</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#D5D7D8;--1:#8F1500">ctx</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">env</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">game</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">load</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">board</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="export class ChessGame extends Agent<Env, State> { initialState: State = { board: new Chess().fen(), players: {}, status: "waiting" }; game = new Chess(); constructor( ctx: DurableObjectState, public env: Env ) { super(ctx, env); this.game.load(this.state.board); }"><div></div></button></div><div class="explain"><button class="explain-button" type="button" data-explain-code="" aria-label="Explain Code"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"></path><path d="M20 3v4"></path><path d="M22 5h-4"></path><path d="M4 17v2"></path><path d="M5 18H3"></path></svg></button></div></figure></div> <p>Each game gets its own Agent instance, enabling:</p> <ul> <li><strong>Isolated state</strong> per game</li> <li><strong>Real-time synchronization</strong> across players</li> <li><strong>Persistent storage</strong> that survives worker restarts</li> </ul> <div tabindex="-1" class="heading-wrapper level-h3"><h3 id="callable-methods">Callable methods</h3><a class="anchor-link" href="#callable-methods"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <p>Use the <code dir="auto">@callable()</code> decorator to expose methods that clients can invoke:</p> <div class="expressive-code"><figure class="frame has-title not-content"><figcaption class="header"><span class="title">TypeScript</span></figcaption><pre data-language="ts"><code><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">@</span><span style="--0:#57C78F;--1:#00783C">callable</span><span style="--0:#EEFFFF;--1:#62676A">()</span></div></div><div class="ec-line"><div class="code"><span style="--0:#57C78F;--1:#00783C">join</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#D5D7D8;--1:#8F1500">params</span><span style="--0:#EEFFFF;--1:#62676A">: </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> playerId</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">string</span><span style="--0:#EEFFFF;--1:#62676A">; </span><span style="--1:#8F1500"><span style="--0:#D5D7D8">preferred</span><span style="--0:#EE9080">?:</span></span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">Color</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">|</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"any"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">playerId</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">preferred</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"any"</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">params</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">connection</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">getCurrentAgent</span><span style="--0:#EE9080;--1:#32008F">()</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--1:#8F1500"><span style="--0:#EE9080">!</span><span style="--0:#D5D7D8">connection</span></span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#EE9080;--1:#8F1500">throw</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">Error</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#FDDA68;--1:#A84E00">"Not connected"</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</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:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">connection</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">setState</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">playerId</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">s</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#89DDFF;--1:#007474">;</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:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic">// Already seated? Return seat</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">already</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">colorOf</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#D5D7D8;--1:#8F1500">playerId</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#D5D7D8;--1:#8F1500">already</span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> ok</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">true</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> role</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">already</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">as</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">Color</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> state</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">s</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</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:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic">// Choose a seat</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">free</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EE9080;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">Color</span><span style="--0:#EE9080;--1:#007474">[] </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> ([</span><span style="--0:#FDDA68;--1:#A84E00">"w"</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"b"</span><span style="--0:#EE9080;--1:#32008F">] </span><span style="--0:#EE9080;--1:#8F1500">as</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">filter</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">c</span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">!</span><span style="--0:#EEFFFF;--1:#00268F">s</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">players</span><span style="--0:#EE9080;--1:#32008F">[</span><span style="--0:#D5D7D8;--1:#8F1500">c</span><span style="--0:#EE9080;--1:#32008F">])</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#EEFFFF;--1:#00268F">free</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#9D5600">length</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">===</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">0</span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> ok</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">true</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> role</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"spectator"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">as</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> state</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">s</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</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:#EE9080;--1:#8F1500">let</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--1:#8F1500"><span style="--0:#D5D7D8">seat</span><span style="--0:#EE9080">:</span></span><span style="--0:#EE9080;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">Color</span><span style="--0:#EE9080;--1:#007474"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">free</span><span style="--0:#EE9080;--1:#32008F">[</span><span style="--0:#B59EE1;--1:#7C008F">0</span><span style="--0:#EE9080;--1:#32008F">]</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#D5D7D8;--1:#8F1500">preferred</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">===</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"w"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">&&</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EEFFFF;--1:#00268F">free</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">includes</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#FDDA68;--1:#A84E00">"w"</span><span style="--0:#EEFFFF;--1:#62676A">)) </span><span style="--0:#D5D7D8;--1:#8F1500">seat</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"w"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#D5D7D8;--1:#8F1500">preferred</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">===</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"b"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">&&</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EEFFFF;--1:#00268F">free</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">includes</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#FDDA68;--1:#A84E00">"b"</span><span style="--0:#EEFFFF;--1:#62676A">)) </span><span style="--0:#D5D7D8;--1:#8F1500">seat</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"b"</span><span style="--0:#89DDFF;--1:#007474">;</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:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">s</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">players</span><span style="--0:#EEFFFF;--1:#62676A">[</span><span style="--0:#D5D7D8;--1:#8F1500">seat</span><span style="--0:#EEFFFF;--1:#62676A">] </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">playerId</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">s</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">status</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EEFFFF;--1:#00268F">s</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">players</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">w</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">&&</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EEFFFF;--1:#00268F">s</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">players</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">b</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">?</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"active"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"waiting"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">setState</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#D5D7D8;--1:#8F1500">s</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> ok</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">true</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> role</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">seat</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> state</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">s</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">}</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="@callable()join(params: { playerId: string; preferred?: Color | "any" }) { const { playerId, preferred = "any" } = params; const { connection } = getCurrentAgent(); if (!connection) throw new Error("Not connected"); connection.setState({ playerId }); const s = this.state; // Already seated? Return seat const already = this.colorOf(playerId); if (already) { return { ok: true, role: already as Color, state: s }; } // Choose a seat const free: Color[] = (["w", "b"] as const).filter((c) => !s.players[c]); if (free.length === 0) { return { ok: true, role: "spectator" as const, state: s }; } let seat: Color = free[0]; if (preferred === "w" && free.includes("w")) seat = "w"; if (preferred === "b" && free.includes("b")) seat = "b"; s.players[seat] = playerId; s.status = s.players.w && s.players.b ? "active" : "waiting"; this.setState(s); return { ok: true, role: seat, state: s };}"><div></div></button></div><div class="explain"><button class="explain-button" type="button" data-explain-code="" aria-label="Explain Code"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"></path><path d="M20 3v4"></path><path d="M22 5h-4"></path><path d="M4 17v2"></path><path d="M5 18H3"></path></svg></button></div></figure></div> <div tabindex="-1" class="heading-wrapper level-h3"><h3 id="react-integration">React integration</h3><a class="anchor-link" href="#react-integration"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <p>The <code dir="auto">useAgent</code> hook connects your React app to the Durable Object:</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:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">stub</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">useAgent</span><span style="--0:#89DDFF;--1:#007474"><</span><span style="--0:#57C78F;--1:#00783C">ServerState</span><span style="--0:#89DDFF;--1:#007474">></span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#D5D7D8;--1:#8F1500">host</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">name</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">gameId</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">??</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"__lobby__"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">agent</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"chess"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">onStateUpdate</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">s</span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EEFFFF;--1:#00268F">gameRef</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">current</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">load</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#EEFFFF;--1:#00268F">s</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">board</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">setFen</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#EEFFFF;--1:#00268F">s</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">board</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">setServerState</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#D5D7D8;--1:#8F1500">s</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="const { stub } = useAgent<ServerState>({ host, name: gameId ?? "__lobby__", agent: "chess", onStateUpdate: (s) => { gameRef.current.load(s.board); setFen(s.board); setServerState(s); },});"><div></div></button></div><div class="explain"><button class="explain-button" type="button" data-explain-code="" aria-label="Explain Code"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"></path><path d="M20 3v4"></path><path d="M22 5h-4"></path><path d="M4 17v2"></path><path d="M5 18H3"></path></svg></button></div></figure></div> <p>Call methods on the agent:</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:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">res</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">await</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">stub</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">join</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">playerId</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> preferred</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"any"</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">await</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EEFFFF;--1:#00268F">stub</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">move</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> from</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"e2"</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> to</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"e4"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="const res = await stub.join({ playerId, preferred: "any" });await stub.move({ from: "e2", to: "e4" });"><div></div></button></div></figure></div> <div tabindex="-1" class="heading-wrapper level-h3"><h3 id="bidirectional-communication">Bidirectional communication</h3><a class="anchor-link" href="#bidirectional-communication"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <p>Your app can send messages to ChatGPT:</p> <div class="expressive-code"><figure class="frame has-title not-content"><figcaption class="header"><span class="title">TypeScript</span></figcaption><pre data-language="ts"><code><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">handleHelpClick</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">()</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EEFFFF;--1:#00268F">window</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">openai</span><span style="--0:#89DDFF;--1:#007474">?.</span><span style="--0:#57C78F;--1:#00783C">sendFollowUpMessage</span><span style="--0:#89DDFF;--1:#007474">?.</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">prompt</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">Help me with my chess game. I am playing as </span><span style="--0:#89DDFF;--1:#007474">${</span><span style="--0:#D5D7D8;--1:#8F1500">myColor</span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#FDDA68;--1:#A84E00"> and the board is: </span><span style="--0:#89DDFF;--1:#007474">${</span><span style="--0:#D5D7D8;--1:#8F1500">fen</span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#FDDA68;--1:#A84E00">. Please only offer written advice as there are no tools for you to use.</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">};</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="const handleHelpClick = () => { window.openai?.sendFollowUpMessage?.({ prompt: `Help me with my chess game. I am playing as ${myColor} and the board is: ${fen}. Please only offer written advice as there are no tools for you to use.`, });};"><div></div></button></div></figure></div> <p>This creates a new message in the ChatGPT conversation with context about the current game state.</p> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="next-steps">Next steps</h2><a class="anchor-link" href="#next-steps"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <p>Now that you have a working ChatGPT App, you can:</p> <ul> <li>Add more tools: Expose additional capabilities and UIs through MCP tools and resources.</li> <li>Enhance the UI: Build more sophisticated interfaces with React.</li> </ul> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="related-resources">Related resources</h2><a class="anchor-link" href="#related-resources"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <div class="sl-link-card astro-lyux3snc"> <span class="sl-flex stack astro-lyux3snc"> <a href="/agents/runtime/agents-api/" class="astro-lyux3snc"> <span class="title astro-lyux3snc">Agents API</span> </a> <span class="description astro-lyux3snc">Complete API reference for the Agents SDK.</span> </span> <svg aria-hidden="true" class="icon rtl:flip astro-lyux3snc astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.333em;"><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> </div> <div class="sl-link-card astro-lyux3snc"> <span class="sl-flex stack astro-lyux3snc"> <a href="/durable-objects/" class="astro-lyux3snc"> <span class="title astro-lyux3snc">Durable Objects</span> </a> <span class="description astro-lyux3snc">Learn about the underlying stateful infrastructure.</span> </span> <svg aria-hidden="true" class="icon rtl:flip astro-lyux3snc astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.333em;"><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> </div> <div class="sl-link-card astro-lyux3snc"> <span class="sl-flex stack astro-lyux3snc"> <a href="https://modelcontextprotocol.io/" class="astro-lyux3snc"> <span class="title astro-lyux3snc">Model Context Protocol</span> </a> <span class="description astro-lyux3snc">MCP specification and documentation.</span> </span> <svg aria-hidden="true" class="icon rtl:flip astro-lyux3snc astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.333em;"><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> </div> <div class="sl-link-card astro-lyux3snc"> <span class="sl-flex stack astro-lyux3snc"> <a href="https://developers.openai.com/apps-sdk/" class="astro-lyux3snc"> <span class="title astro-lyux3snc">OpenAI Apps SDK</span> </a> <span class="description astro-lyux3snc">Official OpenAI Apps SDK reference.</span> </span> <svg aria-hidden="true" class="icon rtl:flip astro-lyux3snc astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.333em;"><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> </div> </div> <footer class="sl-flex astro-fxeopwe4"> <div class="custom-footer-section w-full astro-fxeopwe4"> <div class="grid grid-cols-2 gap-8 pt-6 pb-10 lg:grid-cols-5 astro-fxeopwe4"> <ul class="flex w-full list-none flex-col gap-3 pl-0 astro-fxeopwe4"> <li class="text-xs leading-5 astro-fxeopwe4"> <strong class="astro-fxeopwe4">Resources</strong> </li> <li class="text-sm astro-fxeopwe4"> <a href="/api/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> API </a> </li><li class="text-sm astro-fxeopwe4"> <a href="/fundamentals/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> New to Cloudflare? </a> </li><li class="text-sm astro-fxeopwe4"> <a href="/directory/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> Directory </a> </li><li class="text-sm astro-fxeopwe4"> <a href="/sponsorships/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> Sponsorships </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://github.com/cloudflare" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> Open Source </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://research.cloudflare.com/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> Cloudflare Research </a> </li> </ul><ul class="flex w-full list-none flex-col gap-3 pl-0 astro-fxeopwe4"> <li class="text-xs leading-5 astro-fxeopwe4"> <strong class="astro-fxeopwe4">Support</strong> </li> <li class="text-sm astro-fxeopwe4"> <a href="https://support.cloudflare.com/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> Help Center </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://www.cloudflarestatus.com/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> System Status </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://www.cloudflare.com/trust-hub/compliance-resources/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> Compliance </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://www.cloudflare.com/trust-hub/gdpr/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> GDPR </a> </li> </ul><ul class="flex w-full list-none flex-col gap-3 pl-0 astro-fxeopwe4"> <li class="text-xs leading-5 astro-fxeopwe4"> <strong class="astro-fxeopwe4">Company</strong> </li> <li class="text-sm astro-fxeopwe4"> <a href="https://www.cloudflare.com/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> cloudflare.com </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://www.cloudflare.com/people/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> Our team </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://www.cloudflare.com/careers/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> Careers </a> </li> </ul><ul class="flex w-full list-none flex-col gap-3 pl-0 astro-fxeopwe4"> <li class="text-xs leading-5 astro-fxeopwe4"> <strong class="astro-fxeopwe4">Tools</strong> </li> <li class="text-sm astro-fxeopwe4"> <a href="https://radar.cloudflare.com/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> Cloudflare Radar </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://labs.cloudflare.dev/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> Cloudflare Labs </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://speed.cloudflare.com/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> Speed Test </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://isbgpsafeyet.com/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> Is BGP Safe Yet? </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://ct.cloudflare.com/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> Certificate Transparency </a> </li> </ul><ul class="flex w-full list-none flex-col gap-3 pl-0 astro-fxeopwe4"> <li class="text-xs leading-5 astro-fxeopwe4"> <strong class="astro-fxeopwe4">Community</strong> </li> <li class="text-sm astro-fxeopwe4"> <a href="https://community.cloudflare.com/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> <svg aria-hidden="true" class="astro-fxeopwe4 astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M16.5 16.84c.16-.5.1-.97-.15-1.3-.22-.33-.6-.5-1.06-.53l-8.66-.11a.15.15 0 0 1-.13-.08.21.21 0 0 1-.02-.15.25.25 0 0 1 .2-.15l8.74-.12a3.13 3.13 0 0 0 2.55-1.91l.5-1.3a.25.25 0 0 0 .01-.17 5.68 5.68 0 0 0-10.93-.59 2.58 2.58 0 0 0-3.35.24 2.55 2.55 0 0 0-.67 2.44 3.64 3.64 0 0 0-3.5 4.17.18.18 0 0 0 .17.15h15.98a.22.22 0 0 0 .21-.16l.12-.43Zm2.77-5.56-.24.01c-.06 0-.1.05-.13.1l-.34 1.18c-.15.5-.1.97.16 1.31.22.32.6.5 1.06.52l1.84.12c.06 0 .1.02.14.07.02.04.03.1.02.15a.23.23 0 0 1-.2.15l-1.93.12a3.11 3.11 0 0 0-2.55 1.91l-.14.36c-.03.07.02.14.1.14h6.6a.18.18 0 0 0 .16-.12 4.74 4.74 0 0 0-4.56-6v-.02Z"/></svg> Community forum </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://x.com/cloudflare" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> <svg aria-hidden="true" class="astro-fxeopwe4 astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M 18.242188 2.25 L 21.554688 2.25 L 14.324219 10.507812 L 22.828125 21.75 L 16.171875 21.75 L 10.953125 14.933594 L 4.992188 21.75 L 1.679688 21.75 L 9.40625 12.914062 L 1.257812 2.25 L 8.082031 2.25 L 12.792969 8.480469 Z M 17.082031 19.773438 L 18.914062 19.773438 L 7.082031 4.125 L 5.113281 4.125 Z M 17.082031 19.773438 "/></svg> X </a> </li><li class="text-sm astro-fxeopwe4"> <a href="http://discord.cloudflare.com/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> <svg aria-hidden="true" class="astro-fxeopwe4 astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M20.32 4.37a19.8 19.8 0 0 0-4.93-1.51 13.78 13.78 0 0 0-.64 1.28 18.27 18.27 0 0 0-5.5 0 12.64 12.64 0 0 0-.64-1.28h-.05A19.74 19.74 0 0 0 3.64 4.4 20.26 20.26 0 0 0 .11 18.09l.02.02a19.9 19.9 0 0 0 6.04 3.03l.04-.02a14.24 14.24 0 0 0 1.23-2.03.08.08 0 0 0-.05-.07 13.1 13.1 0 0 1-1.9-.92.08.08 0 0 1 .02-.1 10.2 10.2 0 0 0 .41-.31h.04a14.2 14.2 0 0 0 12.1 0l.04.01a9.63 9.63 0 0 0 .4.32.08.08 0 0 1-.03.1 12.29 12.29 0 0 1-1.9.91.08.08 0 0 0-.02.1 15.97 15.97 0 0 0 1.27 2.01h.04a19.84 19.84 0 0 0 6.03-3.05v-.03a20.12 20.12 0 0 0-3.57-13.69ZM8.02 15.33c-1.18 0-2.16-1.08-2.16-2.42 0-1.33.96-2.42 2.16-2.42 1.21 0 2.18 1.1 2.16 2.42 0 1.34-.96 2.42-2.16 2.42Zm7.97 0c-1.18 0-2.15-1.08-2.15-2.42 0-1.33.95-2.42 2.15-2.42 1.22 0 2.18 1.1 2.16 2.42 0 1.34-.94 2.42-2.16 2.42Z"/></svg> Discord </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://www.youtube.com/cloudflare" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> <svg aria-hidden="true" class="astro-fxeopwe4 astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M23.5 6.2A3 3 0 0 0 21.4 4c-1.9-.5-9.4-.5-9.4-.5s-7.5 0-9.4.5A3 3 0 0 0 .5 6.3C0 8 0 12 0 12s0 4 .5 5.8A3 3 0 0 0 2.6 20c1.9.6 9.4.6 9.4.6s7.5 0 9.4-.6a3 3 0 0 0 2.1-2c.5-2 .5-5.9.5-5.9s0-4-.5-5.8zm-14 9.4V8.4l6.3 3.6-6.3 3.6z"/></svg> YouTube </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://github.com/cloudflare/cloudflare-docs" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> <svg aria-hidden="true" class="astro-fxeopwe4 astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M12 .3a12 12 0 0 0-3.8 23.38c.6.12.83-.26.83-.57L9 21.07c-3.34.72-4.04-1.61-4.04-1.61-.55-1.39-1.34-1.76-1.34-1.76-1.08-.74.09-.73.09-.73 1.2.09 1.83 1.24 1.83 1.24 1.08 1.83 2.81 1.3 3.5 1 .1-.78.42-1.31.76-1.61-2.67-.3-5.47-1.33-5.47-5.93 0-1.31.47-2.38 1.24-3.22-.14-.3-.54-1.52.1-3.18 0 0 1-.32 3.3 1.23a11.5 11.5 0 0 1 6 0c2.28-1.55 3.29-1.23 3.29-1.23.64 1.66.24 2.88.12 3.18a4.65 4.65 0 0 1 1.23 3.22c0 4.61-2.8 5.63-5.48 5.92.42.36.81 1.1.81 2.22l-.01 3.29c0 .31.2.69.82.57A12 12 0 0 0 12 .3Z"/></svg> GitHub </a> </li> </ul> </div> <div class="astro-fxeopwe4"> <ul class="text-cl1-gray-4! dark:text-cl1-gray-7! flex list-inside flex-wrap items-center justify-center gap-3 gap-y-4 pl-0 text-xs astro-fxeopwe4"> <li class="list-none astro-fxeopwe4">© 2026 Cloudflare, Inc.</li> <li class="astro-fxeopwe4"> <a href="https://www.cloudflare.com/privacypolicy/" class="text-cl1-gray-4! dark:text-cl1-gray-7! no-underline astro-fxeopwe4"> Privacy Policy </a> </li><li class="astro-fxeopwe4"> <a href="https://www.cloudflare.com/website-terms/" class="text-cl1-gray-4! dark:text-cl1-gray-7! no-underline astro-fxeopwe4"> Terms of Use </a> </li><li class="astro-fxeopwe4"> <a href="https://www.cloudflare.com/disclosure/" class="text-cl1-gray-4! dark:text-cl1-gray-7! no-underline astro-fxeopwe4"> Report Security Issues </a> </li><li class="astro-fxeopwe4"> <a href="https://www.cloudflare.com/trademark/" class="text-cl1-gray-4! dark:text-cl1-gray-7! no-underline astro-fxeopwe4"> Trademark </a> </li> <li class="astro-fxeopwe4"> <script src="https://ot.www.cloudflare.com/public/vendor/onetrust/scripttemplates/otSDKStub.js" type="text/javascript" charset="UTF-8" data-domain-script="b1e05d49-f072-4bae-9116-bdb78af15448"></script> <script type="text/javascript"> // eslint-disable-next-line @typescript-eslint/no-unused-vars function OptanonWrapper() {} </script> <!-- OneTrust Cookies Settings button start --><div class="inline-flex items-center gap-2 astro-hwxmvrii"> <img src="/_astro/privacyoptions.BWXSiJOZ_1zBYaH.svg" alt="privacy options" loading="lazy" decoding="async" width="26" height="12" class="astro-hwxmvrii"> <button id="ot-sdk-btn" class="ot-sdk-show-settings astro-hwxmvrii">Cookie Settings</button> </div> <!-- OneTrust Cookies Settings button end --> </li> </ul> </div> </div> <div class="starlight-footer-section astro-fxeopwe4"> <div class="pagination-links print:hidden astro-zujpvvea" dir="ltr"> <a href="/workers/demos/" rel="prev" class="astro-zujpvvea"> <svg aria-hidden="true" class="astro-zujpvvea astro-r7kprdcr" 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-zujpvvea"> Previous <br class="astro-zujpvvea"> <span class="link-title astro-zujpvvea">Demos and architectures</span> </span> </a> <a href="/workers/development-testing/" rel="next" class="astro-zujpvvea"> <svg aria-hidden="true" class="astro-zujpvvea astro-r7kprdcr" 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-zujpvvea"> Next <br class="astro-zujpvvea"> <span class="link-title astro-zujpvvea">Development & testing</span> </span> </a> </div> <div class="meta sl-flex astro-fxeopwe4"> <a href="https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/workers/demos/chatgpt-app.mdx" class="sl-flex print:hidden astro-cdtc2x7r"><svg aria-hidden="true" class="astro-cdtc2x7r astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.2em;"><path d="M22 7.24a1 1 0 0 0-.29-.71l-4.24-4.24a1 1 0 0 0-1.1-.22 1 1 0 0 0-.32.22l-2.83 2.83L2.29 16.05a1 1 0 0 0-.29.71V21a1 1 0 0 0 1 1h4.24a1 1 0 0 0 .76-.29l10.87-10.93L21.71 8c.1-.1.17-.2.22-.33a1 1 0 0 0 0-.24v-.14l.07-.05ZM6.83 20H4v-2.83l9.93-9.93 2.83 2.83L6.83 20ZM18.17 8.66l-2.83-2.83 1.42-1.41 2.82 2.82-1.41 1.42Z"/></svg>Edit page</a> <p>Last updated: <time datetime="2026-06-03T15:55:00.000Z">Jun 3, 2026</time></p> </div> </div> <div class="feedback-prompt astro-fxeopwe4"> <astro-island uid="1gAukP" prefix="r3" component-url="/_astro/FeedbackPrompt.FVI-KaJz.js" component-export="default" renderer-url="/_astro/client.hmfmp3Nb.js" props="{}" ssr client="idle" opts="{"name":"FeedbackPrompt","value":true}" await-children><div id="feedback-form"><p class="m-0 text-[11px] font-semibold tracking-widest text-[var(--sl-color-gray-3)] uppercase">Was this helpful?</p><div class="mt-3 flex gap-2"><button class="inline-flex h-8 cursor-pointer items-center gap-1.5 rounded-lg border-0 bg-[var(--sl-color-bg-nav)] px-3 text-[13px] font-medium text-[var(--sl-color-text)] shadow-none ring-1 ring-[var(--sl-color-hairline)] transition-colors duration-150 hover:bg-[var(--color-cl1-gray-9)] hover:ring-[var(--sl-color-gray-3)] dark:hover:bg-[var(--color-cl1-gray-2)]"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" class="opacity-70" height="18" width="18" xmlns="http://www.w3.org/2000/svg"><path fill="none" d="M0 0h24v24H0V0zm0 0h24v24H0V0z"></path><path d="M9 21h9c.83 0 1.54-.5 1.84-1.22l3.02-7.05c.09-.23.14-.47.14-.73v-2c0-1.1-.9-2-2-2h-6.31l.95-4.57.03-.32c0-.41-.17-.79-.44-1.06L14.17 1 7.58 7.59C7.22 7.95 7 8.45 7 9v10c0 1.1.9 2 2 2zM9 9l4.34-4.34L12 10h9v2l-3 7H9V9zM1 9h4v12H1z"></path></svg><span>Yes</span></button><button class="inline-flex h-8 cursor-pointer items-center gap-1.5 rounded-lg border-0 bg-[var(--sl-color-bg-nav)] px-3 text-[13px] font-medium text-[var(--sl-color-text)] shadow-none ring-1 ring-[var(--sl-color-hairline)] transition-colors duration-150 hover:bg-[var(--color-cl1-gray-9)] hover:ring-[var(--sl-color-gray-3)] dark:hover:bg-[var(--color-cl1-gray-2)]"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" class="opacity-70" height="18" width="18" xmlns="http://www.w3.org/2000/svg"><path fill="none" d="M0 0h24v24H0V0zm0 0h24v24H0V0z"></path><path d="M15 3H6c-.83 0-1.54.5-1.84 1.22l-3.02 7.05c-.09.23-.14.47-.14.73v2c0 1.1.9 2 2 2h6.31l-.95 4.57-.03.32c0 .41.17.79.44 1.06L9.83 23l6.59-6.59c.36-.36.58-.86.58-1.41V5c0-1.1-.9-2-2-2zm0 12-4.34 4.34L12 14H3v-2l3-7h9v10zm4-12h4v12h-4z"></path></svg><span>No</span></button></div></div><!--astro:end--></astro-island> </div> </footer> </div> </div> </main> </div> </div> </div> </div> </body></html>
Lưu ý Note ចំណាំ
Lưu ý trước khi làm Notes before you start ចំណាំមុនពេលចាប់ផ្តើម
- Đây là bản tóm tắt trên Orange Cloud Learning Hub — không thay thế tài liệu chính thức.
- Luôn mở liên kết «Tài liệu gốc» bên dưới khi cần lệnh CLI, snippet code và ảnh minh họa đầy đủ.
- Docs Cloudflare cập nhật thường xuyên — đối chiếu ngày «Rà soát lần cuối» trên trang gốc khi triển khai production.
- This is a summary on Orange Cloud Learning Hub — it does not replace the official documentation.
- Open the Official docs link below for CLI commands, code snippets, and full screenshots.
- Cloudflare docs change frequently — verify the Last reviewed date on the official page before production use.
- នេះគឺជាការសង្ខេបនៅលើ Orange Cloud Learning Hub — វាមិនជំនួសឯកសារផ្លូវការទេ។
- បើកតំណឯកសារផ្លូវការខាងក្រោមសម្រាប់ពាក្យបញ្ជា CLI កូដ snippets និងរូបថតអេក្រង់ពេញ។
- Cloudflare ឯកសារផ្លាស់ប្តូរជាញឹកញាប់ — ផ្ទៀងផ្ទាត់កាលបរិច្ឆេទដែលបានពិនិត្យចុងក្រោយនៅលើទំព័រផ្លូវការមុនពេលប្រើប្រាស់ផលិតកម្ម។
Nội dung chi tiết chưa được đồng bộ — mở tài liệu gốc hoặc chạy lại resources:crawl-previews. Detailed content not synced yet — open the official doc or re-run resources:crawl-previews. ខ្លឹមសារលម្អិតមិនទាន់ធ្វើសមកាល — បើកឯកសារផ្លូវការ ឬរត់ resources:crawl-previews ម្ដងទៀត។
Xem bản đầy đủ trên developers.cloudflare.com (ảnh, tab cấu hình). View the full guide on developers.cloudflare.com (images, config tabs). មើលមគ្គុទ្ទេសក៍ពេញលើ developers.cloudflare.com (រូបភាព, tab កំណត់)។
Tài liệu gốc ↗ Official docs ↗ ឯកសារផ្លូវការ ↗