6 6
7> Welcome to Claude Code!7> Welcome to Claude Code!
8 8
9export const InstallConfigurator = () => {
10 const TERM = {
11 mac: {
12 label: 'macOS / Linux',
13 cmd: 'curl -fsSL https://claude.ai/install.sh | bash'
14 },
15 win: {
16 label: 'Windows'
17 },
18 brew: {
19 label: 'Homebrew',
20 cmd: 'brew install --cask claude-code'
21 },
22 winget: {
23 label: 'WinGet',
24 cmd: 'winget install Anthropic.ClaudeCode'
25 }
26 };
27 const WIN_VARIANTS = {
28 ps: 'irm https://claude.ai/install.ps1 | iex',
29 cmd: 'curl -fsSL https://claude.ai/install.cmd -o install.cmd && install.cmd && del install.cmd'
30 };
31 const TABS = [{
32 key: 'terminal',
33 label: 'Terminal'
34 }, {
35 key: 'desktop',
36 label: 'Desktop'
37 }, {
38 key: 'vscode',
39 label: 'VS Code'
40 }, {
41 key: 'jetbrains',
42 label: 'JetBrains'
43 }];
44 const ALT_TARGETS = {
45 desktop: {
46 name: 'Desktop',
47 installLabel: 'Download the app',
48 installHref: 'https://claude.com/download?utm_source=claude_code&utm_medium=docs&utm_content=configurator_desktop_download',
49 guideHref: '/en/desktop-quickstart'
50 },
51 vscode: {
52 name: 'VS Code',
53 installLabel: 'Install from Marketplace',
54 installHref: 'https://marketplace.visualstudio.com/items?itemName=anthropic.claude-code',
55 altCmd: 'code --install-extension anthropic.claude-code',
56 guideHref: '/en/vs-code'
57 },
58 jetbrains: {
59 name: 'JetBrains',
60 installLabel: 'Install from Marketplace',
61 installHref: 'https://plugins.jetbrains.com/plugin/27310-claude-code-beta-',
62 guideHref: '/en/jetbrains'
63 }
64 };
65 const PROVIDERS = [{
66 key: 'anthropic',
67 label: 'Anthropic'
68 }, {
69 key: 'bedrock',
70 label: 'Amazon Bedrock'
71 }, {
72 key: 'foundry',
73 label: 'Microsoft Foundry'
74 }, {
75 key: 'vertex',
76 label: 'Google Vertex AI'
77 }];
78 const PROVIDER_NOTICE = {
79 bedrock: <>
80 <strong>Configure your AWS account first.</strong> Running on Bedrock
81 requires model access enabled in the AWS console and IAM credentials.{' '}
82 <a href="/en/amazon-bedrock">Bedrock setup guide →</a>
83 </>,
84 vertex: <>
85 <strong>Configure your GCP project first.</strong> Running on Vertex AI
86 requires the Vertex API enabled and a service account with the right
87 permissions.{' '}
88 <a href="/en/google-vertex-ai">Vertex setup guide →</a>
89 </>,
90 foundry: <>
91 <strong>Configure your Azure resources first.</strong> Running on
92 Microsoft Foundry requires an Azure subscription with a Foundry resource
93 and model deployments provisioned.{' '}
94 <a href="/en/microsoft-foundry">Foundry setup guide →</a>
95 </>
96 };
97 const iconCheck = (size = 14) => <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
98 <polyline points="20 6 9 17 4 12" />
99 </svg>;
100 const iconCopy = (size = 14) => <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
101 <rect x="9" y="9" width="13" height="13" rx="2" />
102 <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" />
103 </svg>;
104 const iconArrowRight = (size = 13) => <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
105 <line x1="5" y1="12" x2="19" y2="12" />
106 <polyline points="12 5 19 12 12 19" />
107 </svg>;
108 const iconArrowUpRight = (size = 14) => <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
109 <line x1="7" y1="17" x2="17" y2="7" />
110 <polyline points="7 7 17 7 17 17" />
111 </svg>;
112 const iconInfo = (size = 16) => <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
113 <circle cx="12" cy="12" r="10" />
114 <line x1="12" y1="16" x2="12" y2="12" />
115 <line x1="12" y1="8" x2="12.01" y2="8" />
116 </svg>;
117 const [target, setTarget] = useState('terminal');
118 const [team, setTeam] = useState(false);
119 const [provider, setProvider] = useState('anthropic');
120 const [pkg, setPkg] = useState(() => (/Win/).test(navigator.userAgent) ? 'win' : 'mac');
121 const [winCmd, setWinCmd] = useState(false);
122 const [copied, setCopied] = useState(null);
123 const copyTimer = useRef(null);
124 const handleCopy = async (text, key) => {
125 try {
126 await navigator.clipboard.writeText(text);
127 } catch {
128 const ta = document.createElement('textarea');
129 ta.value = text;
130 document.body.appendChild(ta);
131 ta.select();
132 document.execCommand('copy');
133 document.body.removeChild(ta);
134 }
135 clearTimeout(copyTimer.current);
136 setCopied(key);
137 copyTimer.current = setTimeout(() => setCopied(null), 1800);
138 };
139 const cardBodyCmd = (cmd, prompt) => {
140 const on = copied === 'term';
141 return <div className="cc-ic-card-body">
142 <span className="cc-ic-prompt">{prompt || '$'}</span>
143 <div className="cc-ic-cmd">{cmd}</div>
144 <button type="button" className={'cc-ic-copy' + (on ? ' cc-ic-copied' : '')} onClick={() => handleCopy(cmd, 'term')}>
145 {on ? iconCheck(13) : iconCopy(13)}
146 <span>{on ? 'Copied' : 'Copy'}</span>
147 </button>
148 </div>;
149 };
150 const isWinInstaller = pkg === 'win';
151 const isWinPrompt = pkg === 'win' || pkg === 'winget';
152 const terminalCmd = isWinInstaller ? WIN_VARIANTS[winCmd ? 'cmd' : 'ps'] : TERM[pkg].cmd;
153 const alt = ALT_TARGETS[target];
154 const showNotice = team && provider !== 'anthropic';
155 const STYLES = `
156.cc-ic {
157 --ic-slate: #141413;
158 --ic-clay: #d97757;
159 --ic-clay-deep: #c6613f;
160 --ic-gray-000: #ffffff;
161 --ic-gray-150: #f0eee6;
162 --ic-gray-550: #73726c;
163 --ic-gray-700: #3d3d3a;
164 --ic-border-subtle: rgba(31, 30, 29, 0.08);
165 --ic-border-default: rgba(31, 30, 29, 0.15);
166 --ic-border-strong: rgba(31, 30, 29, 0.3);
167 --ic-font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, 'Courier New', monospace;
168 font-family: 'Anthropic Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
169 font-size: 14px; line-height: 1.5; color: var(--ic-slate);
170 margin: 8px 0 32px;
171}
172.dark .cc-ic {
173 --ic-slate: #f0eee6;
174 --ic-gray-000: #262624;
175 --ic-gray-150: #1f1e1d;
176 --ic-gray-550: #91908a;
177 --ic-gray-700: #bfbdb4;
178 --ic-border-subtle: rgba(240, 238, 230, 0.08);
179 --ic-border-default: rgba(240, 238, 230, 0.14);
180 --ic-border-strong: rgba(240, 238, 230, 0.28);
181}
182.dark .cc-ic-check { background: transparent; }
183.dark .cc-ic-card { border: 0.5px solid var(--ic-border-subtle); }
184.dark .cc-ic-p-pill.cc-ic-active { box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3); }
185.cc-ic *, .cc-ic *::before, .cc-ic *::after { box-sizing: border-box; }
186.cc-ic a { text-decoration: none; }
187.cc-ic a:not([class]) { color: inherit; }
188.cc-ic button { font-family: inherit; cursor: pointer; }
189
190.cc-ic-tab-strip {
191 display: inline-flex; gap: 2px;
192 padding: 4px; background: var(--ic-gray-150);
193 border-radius: 10px; overflow-x: auto;
194 max-width: 100%;
195}
196.cc-ic-tab {
197 appearance: none; background: none; border: none;
198 padding: 10px 18px; font-size: 15px; font-weight: 430;
199 color: var(--ic-gray-550); border-radius: 7px;
200 white-space: nowrap;
201 transition: color 0.12s, background-color 0.12s;
202}
203.cc-ic-tab:hover { color: var(--ic-gray-700); }
204.cc-ic-tab.cc-ic-active {
205 color: var(--ic-slate); font-weight: 500;
206 background: var(--ic-gray-000);
207 box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
208}
209.dark .cc-ic-tab.cc-ic-active { box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4); }
210
211.cc-ic-team-wrap { padding: 16px 0 20px; }
212.cc-ic-team-toggle {
213 display: flex; align-items: center; gap: 12px; font-family: inherit;
214 padding: 12px 16px; font-size: 14px; font-weight: 430;
215 color: var(--ic-gray-700); cursor: pointer; user-select: none;
216 width: fit-content; background: var(--ic-gray-150);
217 border: 0.5px solid var(--ic-border-subtle); border-radius: 8px;
218 transition: border-color 0.15s;
219}
220.cc-ic-team-toggle:hover { border-color: var(--ic-border-default); }
221.cc-ic-team-toggle.cc-ic-checked {
222 background: rgba(217, 119, 87, 0.08);
223 border-color: rgba(217, 119, 87, 0.25);
224}
225.cc-ic-check {
226 width: 16px; height: 16px;
227 border: 1px solid var(--ic-border-strong); border-radius: 4px;
228 background: var(--ic-gray-000);
229 display: flex; align-items: center; justify-content: center;
230 flex-shrink: 0;
231}
232.cc-ic-check svg { color: #fff; display: none; }
233.cc-ic-team-toggle.cc-ic-checked .cc-ic-check { background: var(--ic-clay-deep); border-color: var(--ic-clay-deep); }
234.cc-ic-team-toggle.cc-ic-checked .cc-ic-check svg { display: block; }
235
236.cc-ic-team-reveal { display: flex; flex-direction: column; gap: 12px; margin-bottom: 16px; }
237.cc-ic-sales {
238 display: flex; align-items: center; justify-content: space-between;
239 gap: 16px; padding: 14px 16px;
240 background: var(--ic-gray-000); border: 0.5px solid var(--ic-border-default);
241 border-radius: 8px; flex-wrap: wrap;
242}
243.cc-ic-sales-text { font-size: 13px; color: var(--ic-gray-700); line-height: 1.5; flex: 1; min-width: 200px; }
244.cc-ic-sales-text strong { font-weight: 550; color: var(--ic-slate); }
245.cc-ic-sales-actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
246.cc-ic-btn-clay {
247 display: inline-flex; align-items: center; gap: 8px;
248 background: var(--ic-clay-deep); color: #fff; border: none;
249 border-radius: 8px; padding: 8px 14px;
250 font-size: 13px; font-weight: 500;
251 transition: background-color 0.15s; white-space: nowrap;
252}
253.cc-ic-btn-clay:hover { background: var(--ic-clay); }
254.cc-ic-btn-ghost {
255 display: inline-flex; align-items: center; gap: 8px;
256 background: transparent; color: var(--ic-gray-700);
257 border: 0.5px solid var(--ic-border-default);
258 border-radius: 8px; padding: 8px 14px;
259 font-size: 13px; font-weight: 500;
260}
261.cc-ic-btn-ghost:hover { background: rgba(0, 0, 0, 0.04); }
262
263.cc-ic-provider-bar {
264 display: flex; align-items: center; gap: 12px;
265 padding: 14px 16px; background: var(--ic-gray-150);
266 border-radius: 8px; font-size: 13px; flex-wrap: wrap;
267}
268.cc-ic-provider-bar .cc-ic-label { color: var(--ic-gray-550); flex-shrink: 0; }
269.cc-ic-provider-pills { display: flex; gap: 4px; flex-wrap: wrap; }
270.cc-ic-p-pill {
271 appearance: none; border: none; background: transparent;
272 padding: 6px 12px; border-radius: 6px;
273 font-size: 13px; font-weight: 430; color: var(--ic-gray-700);
274 white-space: nowrap;
275}
276.cc-ic-p-pill:hover { background: rgba(0, 0, 0, 0.04); }
277.cc-ic-p-pill.cc-ic-active {
278 background: var(--ic-gray-000); color: var(--ic-slate);
279 font-weight: 500; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
280}
281.cc-ic-provider-notice {
282 display: flex; padding: 16px 18px;
283 background: var(--ic-gray-000); border: 0.5px solid var(--ic-border-default);
284 border-radius: 8px; gap: 14px; align-items: flex-start;
285}
286.cc-ic-provider-notice > svg { color: var(--ic-gray-550); margin-top: 2px; flex-shrink: 0; }
287.cc-ic-provider-notice-body { font-size: 14px; line-height: 1.55; color: var(--ic-gray-700); }
288.cc-ic-provider-notice-body strong { font-weight: 550; color: var(--ic-slate); }
289.cc-ic-provider-notice-body a { color: var(--ic-clay-deep); font-weight: 500; }
290.cc-ic-provider-notice-body a:hover { text-decoration: underline; }
291
292.cc-ic-card { background: #141413; border-radius: 12px; overflow: hidden; }
293.cc-ic-subtabs {
294 display: flex; align-items: center;
295 background: #1a1918;
296 border-bottom: 0.5px solid rgba(255, 255, 255, 0.08);
297 padding: 0 8px; overflow-x: auto;
298}
299.cc-ic-subtab-spacer { flex: 1; }
300.cc-ic-subtab {
301 appearance: none; background: none; border: none;
302 padding: 12px 16px; font-size: 12px;
303 color: rgba(255, 255, 255, 0.5);
304 position: relative; white-space: nowrap;
305}
306.cc-ic-subtab:hover { color: rgba(255, 255, 255, 0.75); }
307.cc-ic-subtab.cc-ic-active { color: #fff; }
308.cc-ic-subtab.cc-ic-active::after {
309 content: ''; position: absolute;
310 left: 12px; right: 12px; bottom: -0.5px;
311 height: 2px; background: var(--ic-clay);
312}
313.cc-ic-cmd-toggle {
314 display: flex; align-items: center; gap: 8px; font-family: inherit;
315 background: none; border: none;
316 padding: 0 12px; font-size: 11px;
317 color: rgba(255, 255, 255, 0.5);
318 cursor: pointer; user-select: none; white-space: nowrap;
319}
320.cc-ic-cmd-toggle:hover { color: rgba(255, 255, 255, 0.75); }
321.cc-ic-mini-check {
322 width: 12px; height: 12px;
323 border: 1px solid rgba(255, 255, 255, 0.3); border-radius: 3px;
324 display: flex; align-items: center; justify-content: center;
325 flex-shrink: 0;
326}
327.cc-ic-mini-check svg { color: #fff; display: none; }
328.cc-ic-cmd-toggle.cc-ic-checked .cc-ic-mini-check { background: var(--ic-clay-deep); border-color: var(--ic-clay-deep); }
329.cc-ic-cmd-toggle.cc-ic-checked .cc-ic-mini-check svg { display: block; }
330
331.cc-ic-card-body { padding: 24px 26px; display: flex; align-items: flex-start; gap: 14px; }
332.cc-ic-prompt {
333 color: var(--ic-clay); font-family: var(--ic-font-mono);
334 font-size: 17px; user-select: none; padding-top: 2px;
335}
336.cc-ic-cmd {
337 flex: 1; font-family: var(--ic-font-mono);
338 font-size: 17px; color: #f0eee6;
339 line-height: 1.55; white-space: pre-wrap; word-break: break-word;
340}
341.cc-ic-copy {
342 display: inline-flex; align-items: center; gap: 6px;
343 background: rgba(255, 255, 255, 0.08);
344 border: 0.5px solid rgba(255, 255, 255, 0.12);
345 color: rgba(255, 255, 255, 0.85);
346 padding: 7px 13px; border-radius: 8px;
347 font-size: 13px; font-weight: 500; flex-shrink: 0;
348}
349.cc-ic-copy:hover { background: rgba(255, 255, 255, 0.14); }
350.cc-ic-copy.cc-ic-copied { background: var(--ic-clay-deep); border-color: var(--ic-clay-deep); color: #fff; }
351
352.cc-ic-below {
353 margin-top: 12px; font-size: 13px; color: var(--ic-gray-550);
354 display: flex; gap: 16px; flex-wrap: wrap; align-items: baseline;
355}
356.cc-ic-below a { color: var(--ic-gray-700); border-bottom: 0.5px solid var(--ic-border-default); }
357.cc-ic-below a:hover { color: var(--ic-clay-deep); border-bottom-color: var(--ic-clay-deep); }
358.cc-ic-handoff {
359 padding: 20px 22px;
360 background: var(--ic-gray-000);
361 border: 0.5px solid var(--ic-border-default);
362 border-radius: 12px;
363}
364.cc-ic-handoff-head {
365 font-size: 14px; line-height: 1.55; color: var(--ic-gray-700);
366 margin-bottom: 14px;
367}
368.cc-ic-handoff-head strong { font-weight: 550; color: var(--ic-slate); }
369.cc-ic-handoff-actions { display: flex; gap: 10px; flex-wrap: wrap; }
370.cc-ic-handoff-alt {
371 margin-top: 12px; font-size: 12px; color: var(--ic-gray-550);
372}
373.cc-ic-handoff-alt code {
374 font-family: var(--ic-font-mono); font-size: 11px;
375 background: var(--ic-gray-150); padding: 2px 6px;
376 border-radius: 4px; color: var(--ic-gray-700);
377}
378.cc-ic-copy-sm {
379 appearance: none; border: none;
380 display: inline-flex; align-items: center; justify-content: center;
381 width: 22px; height: 22px;
382 margin-left: 4px; vertical-align: middle;
383 background: var(--ic-gray-150); color: var(--ic-gray-550);
384 border-radius: 4px;
385 transition: color 0.1s, background-color 0.1s;
386}
387.cc-ic-copy-sm:hover { color: var(--ic-gray-700); background: var(--ic-border-default); }
388.cc-ic-copy-sm.cc-ic-copied { background: var(--ic-clay-deep); color: #fff; }
389
390@media (max-width: 720px) {
391 .cc-ic-tab { padding: 12px 14px; font-size: 14px; }
392 .cc-ic-sales-actions { width: 100%; }
393 .cc-ic-card-body { padding: 20px; }
394 .cc-ic-cmd { font-size: 15px; }
395}
396`;
397 return <div className="cc-ic not-prose">
398 <style>{STYLES}</style>
399
400 {}
401 <div className="cc-ic-tab-strip" role="tablist">
402 {TABS.map(t => <button key={t.key} type="button" role="tab" aria-selected={target === t.key} className={'cc-ic-tab' + (target === t.key ? ' cc-ic-active' : '')} onClick={() => setTarget(t.key)}>
403 {t.label}
404 </button>)}
405 </div>
406
407 {}
408 <div className="cc-ic-team-wrap">
409 <button type="button" role="switch" aria-checked={team} className={'cc-ic-team-toggle' + (team ? ' cc-ic-checked' : '')} onClick={() => setTeam(!team)}>
410 <span className="cc-ic-check">{iconCheck(11)}</span>
411 <span>
412 I’m buying for a team or company (SSO, AWS/Azure/GCP, central billing)
413 </span>
414 </button>
415 </div>
416
417 {}
418 {team && <div className="cc-ic-team-reveal">
419 <div className="cc-ic-sales">
420 <div className="cc-ic-sales-text">
421 <strong>Set up your team:</strong> self-serve or talk to sales.
422 </div>
423 <div className="cc-ic-sales-actions">
424 <a href="https://claude.ai/upgrade?initialPlanType=team&utm_source=claude_code&utm_medium=docs&utm_content=configurator_team_get_started" className="cc-ic-btn-ghost">
425 Get started
426 </a>
427 <a href="https://www.anthropic.com/contact-sales?utm_source=claude_code&utm_medium=docs&utm_content=configurator_team_contact_sales" className="cc-ic-btn-clay">
428 Contact sales {iconArrowRight()}
429 </a>
430 </div>
431 </div>
432
433 <div className="cc-ic-provider-bar">
434 <span className="cc-ic-label">Run on</span>
435 <div className="cc-ic-provider-pills" role="radiogroup" aria-label="Provider">
436 {PROVIDERS.map(p => <button key={p.key} type="button" role="radio" aria-checked={provider === p.key} className={'cc-ic-p-pill' + (provider === p.key ? ' cc-ic-active' : '')} onClick={() => setProvider(p.key)}>
437 {p.label}
438 </button>)}
439 </div>
440 </div>
441
442 {showNotice && <div className="cc-ic-provider-notice">
443 {iconInfo()}
444 <div className="cc-ic-provider-notice-body">
445 {PROVIDER_NOTICE[provider]}
446 </div>
447 </div>}
448 </div>}
449
450 {}
451 {target === 'terminal' && <div className="cc-ic-card">
452 <div className="cc-ic-subtabs" role="tablist" aria-label="Install method">
453 {Object.keys(TERM).map(k => <button key={k} type="button" role="tab" aria-selected={pkg === k} className={'cc-ic-subtab' + (pkg === k ? ' cc-ic-active' : '')} onClick={() => setPkg(k)}>
454 {TERM[k].label}
455 </button>)}
456 <span className="cc-ic-subtab-spacer" />
457 {isWinInstaller && <button type="button" role="switch" aria-checked={winCmd} className={'cc-ic-cmd-toggle' + (winCmd ? ' cc-ic-checked' : '')} onClick={() => setWinCmd(!winCmd)}>
458 <span className="cc-ic-mini-check">{iconCheck(9)}</span>
459 <span>CMD instead of PowerShell</span>
460 </button>}
461 </div>
462 {cardBodyCmd(terminalCmd, isWinPrompt ? '>' : '$')}
463 </div>}
464
465 {}
466 {target === 'terminal' && <div className="cc-ic-below">
467 {isWinInstaller && <span>
468 Requires{' '}
469 <a href="https://git-scm.com/downloads/win" target="_blank" rel="noopener">
470 Git for Windows
471 </a>.
472 </span>}
473 {(pkg === 'brew' || pkg === 'winget') && <span>
474 Does not auto-update. Run{' '}
475 <code>{pkg === 'brew' ? 'brew upgrade claude-code' : 'winget upgrade Anthropic.ClaudeCode'}</code>{' '}
476 periodically.
477 </span>}
478 <a href="/en/troubleshooting">Troubleshooting</a>
479 </div>}
480
481 {alt && <div className="cc-ic-handoff">
482 <div className="cc-ic-handoff-head">
483 <strong>The steps below use the command line.</strong>{' '}
484 Prefer {alt.name}? Install here, then follow the {alt.name} guide instead.
485 </div>
486 <div className="cc-ic-handoff-actions">
487 <a href={alt.installHref} className="cc-ic-btn-clay" {...alt.installHref.startsWith('http') ? {
488 target: '_blank',
489 rel: 'noopener'
490 } : {}}>
491 {alt.installLabel} {iconArrowUpRight(13)}
492 </a>
493 <a href={alt.guideHref} className="cc-ic-btn-ghost">
494 {alt.name} guide {iconArrowRight(12)}
495 </a>
496 </div>
497 {alt.altCmd && <div className="cc-ic-handoff-alt">
498 or run <code>{alt.altCmd}</code>
499 <button type="button" className={'cc-ic-copy-sm' + (copied === 'alt' ? ' cc-ic-copied' : '')} onClick={() => handleCopy(alt.altCmd, 'alt')} aria-label="Copy command">
500 {copied === 'alt' ? iconCheck(11) : iconCopy(11)}
501 </button>
502 </div>}
503 </div>}
504 </div>;
505};
506
507export const Experiment = ({flag, treatment, children}) => {
508 const VID_KEY = 'exp_vid';
509 const CONSENT_COUNTRIES = new Set(['AT', 'BE', 'BG', 'HR', 'CY', 'CZ', 'DK', 'EE', 'FI', 'FR', 'DE', 'GR', 'HU', 'IE', 'IT', 'LV', 'LT', 'LU', 'MT', 'NL', 'PL', 'PT', 'RO', 'SK', 'SI', 'ES', 'SE', 'RE', 'GP', 'MQ', 'GF', 'YT', 'BL', 'MF', 'PM', 'WF', 'PF', 'NC', 'AW', 'CW', 'SX', 'FO', 'GL', 'AX', 'GB', 'UK', 'AI', 'BM', 'IO', 'VG', 'KY', 'FK', 'GI', 'MS', 'PN', 'SH', 'TC', 'GG', 'JE', 'IM', 'CA', 'BR', 'IN']);
510 const fnv1a = s => {
511 let h = 0x811c9dc5;
512 for (let i = 0; i < s.length; i++) {
513 h ^= s.charCodeAt(i);
514 h += (h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24);
515 }
516 return h >>> 0;
517 };
518 const bucket = (seed, vid) => fnv1a(fnv1a(seed + vid) + '') % 10000 < 5000 ? 'control' : 'treatment';
519 const [decision] = useState(() => {
520 const params = new URLSearchParams(location.search);
521 const force = params.get('gb-force');
522 if (force) {
523 for (const p of force.split(',')) {
524 const [k, v] = p.split(':');
525 if (k === flag) return {
526 variant: v || 'treatment',
527 track: false
528 };
529 }
530 }
531 if (navigator.globalPrivacyControl) {
532 return {
533 variant: 'control',
534 track: false
535 };
536 }
537 const prefsMatch = document.cookie.match(/(?:^|; )anthropic-consent-preferences=([^;]+)/);
538 if (prefsMatch) {
539 try {
540 if (JSON.parse(decodeURIComponent(prefsMatch[1])).analytics !== true) {
541 return {
542 variant: 'control',
543 track: false
544 };
545 }
546 } catch {
547 return {
548 variant: 'control',
549 track: false
550 };
551 }
552 } else {
553 const country = params.get('country')?.toUpperCase() || (document.cookie.match(/(?:^|; )cf_geo=([A-Z]{2})/) || [])[1];
554 if (!country || CONSENT_COUNTRIES.has(country)) {
555 return {
556 variant: 'control',
557 track: false
558 };
559 }
560 }
561 let vid;
562 try {
563 const ajsMatch = document.cookie.match(/(?:^|; )ajs_anonymous_id=([^;]+)/);
564 if (ajsMatch) {
565 vid = decodeURIComponent(ajsMatch[1]).replace(/^"|"$/g, '');
566 } else {
567 vid = localStorage.getItem(VID_KEY);
568 if (!vid) {
569 vid = crypto.randomUUID();
570 }
571 document.cookie = `ajs_anonymous_id=${vid}; domain=.claude.com; path=/; Secure; SameSite=Lax; max-age=31536000`;
572 }
573 try {
574 localStorage.setItem(VID_KEY, vid);
575 } catch {}
576 } catch {
577 return {
578 variant: 'control',
579 track: false
580 };
581 }
582 return {
583 variant: bucket(flag, vid),
584 track: true,
585 vid
586 };
587 });
588 useEffect(() => {
589 if (!decision.track) return;
590 fetch('https://api.anthropic.com/api/event_logging/v2/batch', {
591 method: 'POST',
592 headers: {
593 'Content-Type': 'application/json',
594 'x-service-name': 'claude_code_docs'
595 },
596 body: JSON.stringify({
597 events: [{
598 event_type: 'GrowthbookExperimentEvent',
599 event_data: {
600 device_id: decision.vid,
601 anonymous_id: decision.vid,
602 timestamp: new Date().toISOString(),
603 experiment_id: flag,
604 variation_id: decision.variant === 'treatment' ? 1 : 0,
605 environment: 'production'
606 }
607 }]
608 }),
609 keepalive: true
610 }).catch(() => {});
611 }, []);
612 return decision.variant === 'treatment' ? treatment : children;
613};
614
9This quickstart guide will have you using AI-powered coding assistance in a few minutes. By the end, you'll understand how to use Claude Code for common development tasks.615This quickstart guide will have you using AI-powered coding assistance in a few minutes. By the end, you'll understand how to use Claude Code for common development tasks.
10 616
617<Experiment flag="quickstart-install-configurator" treatment={<InstallConfigurator />} />
618
11## Before you begin619## Before you begin
12 620
13Make sure you have:621Make sure you have: