Skip to content

Commit 0fe0fc0

Browse files
M1zzclaude
andcommitted
feat: add ko/en bilingual support to all pages
- Create lang.js (root + chapters/) for language toggle system - Inject language toggle button (KO/EN) on all pages via lang.js - Add FOUC prevention for language in all HTML heads - Add .lang-ko / .lang-en CSS classes with localStorage persistence - Bilingualize all 14 chapter files + index.html + 404.html - All section titles, nav links, hero text, UI labels translated - Code blocks preserved as-is (commands not translated) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent d5f7b7f commit 0fe0fc0

18 files changed

Lines changed: 4851 additions & 2896 deletions

404.html

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
<html lang="ko">
33
<head>
44
<meta charset="UTF-8">
5+
<script>(function(){var l=localStorage.getItem('cc101-lang')||'ko';document.documentElement.setAttribute('lang',l)})();</script>
56
<meta name="viewport" content="width=device-width, initial-scale=1.0">
67
<title>404 — Claude Code 101</title>
78
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;600&family=Outfit:wght@600;800&display=swap" rel="stylesheet">
@@ -14,14 +15,17 @@
1415
p{color:#64748b;margin-bottom:2rem;font-size:.95rem}
1516
a{display:inline-flex;align-items:center;gap:8px;padding:10px 24px;background:rgba(249,115,22,.12);border:1px solid rgba(249,115,22,.25);border-radius:100px;color:#f97316;text-decoration:none;font-family:'JetBrains Mono',monospace;font-size:.88rem;transition:all .3s}
1617
a:hover{background:rgba(249,115,22,.2);transform:translateY(-1px)}
18+
html[lang="ko"] .lang-en{display:none}
19+
html[lang="en"] .lang-ko{display:none}
1720
</style>
1821
</head>
1922
<body>
2023
<div class="wrap">
2124
<div class="code">404</div>
22-
<h1>페이지를 찾을 수 없습니다</h1>
23-
<p>요청하신 페이지가 존재하지 않거나 이동되었습니다.</p>
24-
<a href="./">← 학습 페이지로 돌아가기</a>
25+
<h1><span class="lang-ko">페이지를 찾을 수 없습니다</span><span class="lang-en">Page Not Found</span></h1>
26+
<p><span class="lang-ko">요청하신 페이지가 존재하지 않거나 이동되었습니다.</span><span class="lang-en">The page you requested doesn't exist or has been moved.</span></p>
27+
<a href="./"><span class="lang-ko">← 학습 페이지로 돌아가기</span><span class="lang-en">← Back to Learning</span></a>
2528
</div>
29+
<script src="lang.js"></script>
2630
</body>
2731
</html>

chapters/advanced.html

Lines changed: 245 additions & 195 deletions
Large diffs are not rendered by default.

chapters/agents.html

Lines changed: 254 additions & 209 deletions
Large diffs are not rendered by default.

chapters/basics.html

Lines changed: 380 additions & 256 deletions
Large diffs are not rendered by default.

chapters/bigpicture.html

Lines changed: 83 additions & 33 deletions
Large diffs are not rendered by default.

chapters/claude-md.html

Lines changed: 296 additions & 192 deletions
Large diffs are not rendered by default.

chapters/concepts.html

Lines changed: 240 additions & 223 deletions
Large diffs are not rendered by default.

chapters/install.html

Lines changed: 480 additions & 221 deletions
Large diffs are not rendered by default.

chapters/lang.js

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/**
2+
* Claude Code 101 — Language Toggle (ko / en)
3+
*
4+
* Usage:
5+
* 1. Add in <head>:
6+
* <script>(function(){var l=localStorage.getItem('cc101-lang')||'ko';document.documentElement.setAttribute('lang',l)})();</script>
7+
* 2. Add before </body>:
8+
* <script src="lang.js"></script>
9+
* 3. Wrap Korean content: <div class="lang-ko">...</div>
10+
* Add English content: <div class="lang-en">...</div>
11+
*/
12+
13+
(function () {
14+
const KEY = 'cc101-lang';
15+
16+
function getLang() {
17+
return localStorage.getItem(KEY) || 'ko';
18+
}
19+
20+
function setLang(lang) {
21+
localStorage.setItem(KEY, lang);
22+
document.documentElement.setAttribute('lang', lang);
23+
const btn = document.getElementById('langToggle');
24+
if (btn) updateBtnText(btn, lang);
25+
}
26+
27+
function updateBtnText(btn, lang) {
28+
btn.textContent = lang === 'ko' ? 'EN' : '한';
29+
btn.title = lang === 'ko' ? 'Switch to English' : '한국어로 변경';
30+
}
31+
32+
function injectStyles() {
33+
if (document.getElementById('lang-styles')) return;
34+
const s = document.createElement('style');
35+
s.id = 'lang-styles';
36+
s.textContent = `
37+
html[lang="ko"] .lang-en { display: none !important; }
38+
html[lang="en"] .lang-ko { display: none !important; }
39+
40+
.lang-toggle {
41+
position: fixed;
42+
bottom: 9.5rem;
43+
right: 1.8rem;
44+
z-index: 1000;
45+
width: 44px;
46+
height: 44px;
47+
border-radius: 50%;
48+
background: var(--surface, #f1f5f9);
49+
border: 1.5px solid var(--border, #e2e8f0);
50+
cursor: pointer;
51+
font-size: 0.72rem;
52+
font-weight: 700;
53+
font-family: var(--font-mono, 'JetBrains Mono', monospace);
54+
color: var(--text, #0f172a);
55+
display: flex;
56+
align-items: center;
57+
justify-content: center;
58+
transition: all .2s;
59+
box-shadow: 0 2px 8px rgba(0,0,0,.1);
60+
line-height: 1;
61+
padding: 0;
62+
}
63+
.lang-toggle:hover {
64+
border-color: var(--accent, #ea6c0a);
65+
transform: scale(1.1);
66+
box-shadow: 0 4px 14px rgba(0,0,0,.15);
67+
}
68+
[data-theme="dark"] .lang-toggle {
69+
background: var(--surface, #1e293b);
70+
border-color: var(--border, #334155);
71+
color: var(--text, #e2e8f0);
72+
box-shadow: 0 2px 8px rgba(0,0,0,.3);
73+
}
74+
`;
75+
document.head.appendChild(s);
76+
}
77+
78+
function injectButton() {
79+
if (document.getElementById('langToggle')) return;
80+
const btn = document.createElement('button');
81+
btn.id = 'langToggle';
82+
btn.className = 'lang-toggle';
83+
btn.setAttribute('aria-label', 'Toggle language / 언어 전환');
84+
updateBtnText(btn, getLang());
85+
btn.onclick = function () {
86+
setLang(getLang() === 'ko' ? 'en' : 'ko');
87+
};
88+
document.body.appendChild(btn);
89+
}
90+
91+
// Apply language immediately for FOUC prevention
92+
document.documentElement.setAttribute('lang', getLang());
93+
injectStyles();
94+
95+
if (document.readyState === 'loading') {
96+
document.addEventListener('DOMContentLoaded', injectButton);
97+
} else {
98+
injectButton();
99+
}
100+
})();

0 commit comments

Comments
 (0)