ã鱿«2æ¥ãClaude Codeã§ã³ãã¥ããã£ããŒã¿ã«ãµã€ããæ§ç¯ã»ãªãªãŒã¹ãããŸã§ã®å šèšé²
ã¯ããã«
ããã«ã¡ã¯ïŒãšã³ãžãã¢ãªã³ã°ã³ãã¥ããã£ãEasy Easyãã®éå¶ã»åºå ±ãæ åœããŠãã@unsoluble_sugarã§ãã
æ¬ã³ãã¥ããã£ã§ã¯ãæ1åã®LTã€ãã³ããå®å šã«çè§£ããTalkãã2019幎æ«ããéå¬ããŠããŸãããããŸã§ç¶ç¶çã«ã€ãã³ããéããå€ãã®ç»å£è ã«ããçºè¡šãèç©ãããŠããŸããã

ã¡ã³ããŒæå¿ã®æ¹ããŸãšããŠãããŠãããªã³ã¯éã¯ãã£ããã®ã®ããã©ãããã©ãŒã ã®æ§è³ªäžãå€è§çãªæ€çŽ¢ãæ å ±éçŽã®UXãšããŠã¯ç©è¶³ããªãéšåããããããã®è©±ãã©ã®åã ã£ãïŒããâ¯â¯ããã®ãããŸã§ã®LTäžèЧãèŠããããšãã£ãèŠæãæºããã®ãé£ããç¶æ³ã§ããã
ããã§ããããã®æ å ±ãäžç®æã«éçŽããããŒã¿ã«ãµã€ããäœãããšã«ããŸããã

ä»åã¯ãã®ãµã€ãã Claude Code ãšäžç·ã«äœãã鱿«2æ¥éã§ãªãªãŒã¹ã«æŒãçãããŸã§ã®éçšãäœãããšãªããäŒãããŸãã
æè¡ã¹ã¿ãã¯ã®éžå®
ä»åã®ãµã€ãã¯ãéå»ã®ã€ãã³ãæ å ±ã»çºè¡šè³æã»ç»å£è æ å ±ãéçŽããŠé²èЧããã ãã®ã·ã³ãã«ãªãã®ã§ããåçãªæ©èœããã°ã€ã³ãæžã蟌ã¿çãäžèŠãªãããéçãµã€ããšããŠæ§ç¯ããæ¹éã§é²ããŸããã
Next.js ã Hugo ãšãã£ããã¬ãŒã ã¯ãŒã¯ãéžæè¢ã«ãããŸããããã€ãã³ãããŒã¿ãéçHTMLã«å€æããã ãã®ã·ã³ãã«ãªæ§æã«ããŸãããããŒã¿ã®è¿œå ã»ä¿®æ£ã YAML ãã¡ã€ã«ãç·šéããã ãã§æžãã®ã§ãã¡ã³ããã³ã¹ããããèšèšã§ãã
- ããŒã¿ç®¡ç: YAMLïŒã€ãã³ãããšã«ãã¡ã€ã«åå²ïŒ
- ãã«ã: Python + Jinja2ïŒãã³ãã¬ãŒããšã³ãžã³ïŒ
- ãã¹ãã£ã³ã°: GitHub Pages
- CI/CD: GitHub ActionsïŒpushã§èªåãã«ãïŒãããã€ïŒ
ãã¹ãã£ã³ã°å 㯠GitHub Pages ãæ¡çšããŸãããå人ã§äœ¿ãå°èŠæš¡ãªWebãµãŒãã¹ããã€ãã³ãŒãã£ã³ã°ããéã«æè»œã§éå®ããŠããã以åã®èšäºã§ãGitHub Pagesã䜿ã£ãå人ããŒã«ã®éçºã«ã€ããŠæžããŠããŸãã
CLAUDE.mdãšã«ãŒã«ãã¡ã€ã«ã«ããã³ã³ããã¹ãå ±æ
Claude Code ã䜿ã£ãéçºã§éèŠã ã£ãã®ã CLAUDE.md ãš .claude/rules/ ã®æŽåã§ãã
Claude Code 㯠CLAUDE.md ãæ¯åã®äŒè©±ã§èªåçã«èªã¿èŸŒãããããååã®äŒè©±ã§äŒããããšããç¹°ãè¿ãå¿
èŠããããŸããããããžã§ã¯ãã®æ§ææŠèŠããã«ãã³ãã³ããããŒã¿è¿œå ã¯ãŒã¯ãããŒãªã©ãèšèŒããŠããŸãã
CLAUDE.md # ãããžã§ã¯ãã¬ã€ãïŒæ§ææŠèŠã»éçºã³ãã³ãïŒ
.claude/rules/
âââ development.md # éçºã«ãŒã«ã»ã³ãŒãã£ã³ã°èŠçŽ
âââ speaker_profile.md # ç»å£è
ãããã£ãŒã«ç®¡çã«ãŒã«
docs/specs/ # 仿§æžïŒããŒãžèšèšãããŒã¿ã¹ããŒãçïŒ
ãã¡ã€ã³åºæã®ã«ãŒã«ïŒç»å£è
ããŒã¿ã®äžå
ç®¡çæ¹éãã¢ã€ã³ã³URLã®åªå
床ãªã©ïŒã¯ .claude/rules/ ã«åé¢ããŠããŸãããã¡ããèªåèªã¿èŸŒã¿ããããããããŒã¿è¿œå æã«ã«ãŒã«ã«æ²¿ã£ã察å¿ãããŠãããŸãã
CLAUDE.md èªäœã«ã¯å
šäœåã®ææ¡ã«å¿
èŠãªæå°éã®æ
å ±ã ããæ®ãã詳现ã¯åããã¥ã¡ã³ããžã®ãã€ã³ã¿ã§åç
§ããæ§æã«ããŠããŸããæ
å ±ã®éè€ãé¿ãã€ã€ãã³ã³ããã¹ããŠã£ã³ããŠã®æ¶è²»ãæããããŸãã
ãªããä»åã¯ç°¡æçãªãµã€ãæ§ç¯ãšããããšããããClaude Codeã®hooksãskillsãšãã£ãæ©èœã¯æŽ»çšããŠããŸãããCLAUDE.md ãš .claude/rules/ ã«ããã³ã³ããã¹ãå
±æã ãã§ååé²ããããŸãããããæ¬æ Œçãªéçºã§ã¯ããããã®ä»çµã¿ãçµã¿åãããããšã§ããã«å¹çåã§ãããšæããŸãã
ã¡ãªã¿ã«ãçè ãä»äºã§æºãã£ãŠããã²ãŒã ãããžã§ã¯ãã§ã¯ãSkillã䜿ã£ãE2Eãã¹ãèªååã«ãåãçµãã§ããŸããèå³ã®ããæ¹ã¯ãã¡ãã®èšäºãã芧ãã ããã
以äžãå®éã«äœ¿çšããŠãããã¡ã€ã«ã®å 容ã§ãã
CLAUDE.md
EasyEasy Community Portal
ãšã³ãžãã¢ãªã³ã°ã³ãã¥ããã£ãEasyEasyãã®ããŒã¿ã«ãµã€ãïŒéçãµã€ãïŒ
å¿çã«ãŒã«
- æ¥æ¬èªã§å¿çããããš
- ããŒã¿/ãã³ãã¬ãŒã倿ŽåŸã¯
python src/build.pyã§ãªãã«ãããããš
éçºã³ãã³ã
pip install -r requirements.txt # äŸåããã±ãŒãž
python src/build.py # ãµã€ããã«ã â output/ ã«åºå
æ§ææŠèŠ
- ãã«ã: Python + Jinja2 â éçHTMLçæ â GitHub Pages
-
ããŒã¿:
data/events/NNN.yamlïŒã€ãã³ãïŒãdata/speakers.yamlïŒç»å£è ãã¹ã¿ãŒïŒãdata/community.yamlïŒãµã€ãèšå®ïŒ -
ãã³ãã¬ãŒã:
src/templates/ïŒbase, index, event_detail, speakers, challenge, aboutïŒ -
ã¢ã»ãã:
assets/ïŒcss, js, imagesïŒ -
èšå®:
src/config/settings.py -
åºå:
output/ïŒgit管çå€ãã¯ãªãŒã³URL圢åŒããŒãžå/index.htmlïŒ
ããŒã¿è¿œå ã¯ãŒã¯ãããŒ
-
data/events/ã« YAML 远å ïŒäŸ:077.yamlïŒ - æ°èŠç»å£è
ã¯
data/speakers.yamlã«è¿œå -
python src/build.pyã§ãã«ã - Git push â GitHub Actions ã§èªåãããã€
詳现: ç»å£è
管ç㯠.claude/rules/speaker_profile.mdãããŒã¿ã¹ããŒã㯠docs/specs/02_data_schema.md ãåç
§ã
.claude/rules/development.md
éçºã«ãŒã«
ã³ãŒãã£ã³ã°èŠçŽ
- Python 3.9+ äºæã®ã³ãŒããæžã
- åãã³ããæŽ»çšãã
- docstring 㯠Google ã¹ã¿ã€ã«ã§èšè¿°ãã
Git ã¯ãŒã¯ãããŒ
- ã³ãããã¡ãã»ãŒãžã¯æ¥æ¬èª OK
- æ©èœåäœã§å°ããã³ããããã
- main ãã©ã³ãã«çŽæ¥ããã·ã¥å¯
ãã³ãã¬ãŒã
- Jinja2 ãã³ãã¬ãŒãã¯
src/templates/ã«é 眮 - ãã³ãã¬ãŒãå ã®ã³ã¡ã³ã㯠HTML ã³ã¡ã³ã圢åŒã§
ããŒã¿ç®¡ç
- ã€ãã³ãããŒã¿ã¯
data/events/NNN.yamlåœ¢åŒ - NNN ã¯ãŒãåã3æ¡ã®ã€ãã³ãçªå·ïŒäŸ: 001, 076ïŒ
- YAML ã®æåã³ãŒã㯠UTF-8
.claude/rules/speaker_profile.md
ç»å£è ãããã£ãŒã«ç®¡çã«ãŒã«
ããŒã¿ç®¡çæ¹é
ç»å£è
ã®ãããã£ãŒã«æ
å ±ã¯ data/speakers.yaml ã§äžå
管çããã
åã€ãã³ãYAMLïŒdata/events/NNN.yamlïŒã«ã¯ speaker.id ãš speaker.name ã®ã¿èšèŒãã
SNSã¢ã«ãŠã³ããã¢ã€ã³ã³URLçã®ãããã£ãŒã«æ
å ±ã¯èšèŒããªãã
ãã«ãæã« speakers.yaml ã®æ
å ±ãã€ãã³ãYAMLã® speaker.id ãšããŒãžãããã
ã¢ã€ã³ã³ç»åã®ååŸã»é©çšåªå 床
ç»å£è ã®ã¢ã€ã³ã³ç»åURLã¯ä»¥äžã®åªå 床ã§é©çšããããã«ãæã«èªå解決ãããã
-
icon_url:
icon_urlãã£ãŒã«ãã«çŽæ¥æå®ããã URLïŒX(pbs.twimg.com)ãconnpass(media.connpass.com) çïŒ -
GitHub:
https://github.com/{github_username}.pngïŒicon_url æªèšå®æã®ãã©ãŒã«ããã¯ïŒ
â» unavatar.io/x ã¯ã¬ãŒãå¶éãå³ããäžå®å®ãªãã䜿çšããªãã
â» Xã®ã¢ã€ã³ã³ãåªå
ãããå Žåã¯ãicon_url ã« pbs.twimg.com ã® URL ãèšå®ããã
speakers.yaml ã®ãã©ãŒããã
- id: speaker_id # äžæã®IDïŒå¿
é ïŒ
name: 衚瀺å # 衚瀺åïŒå¿
é ïŒ
icon_url: "" # connpassã¢ã€ã³ã³çïŒä»»æãäžèšåªå
床ã§èªå解決ïŒ
twitter: "" # X(Twitter)ã¢ã«ãŠã³ãåïŒ@ãªãïŒ
github: "" # GitHubã¢ã«ãŠã³ãå
qiita: "" # Qiitaã¢ã«ãŠã³ãåïŒä»»æïŒ
zenn: "" # Zennã¢ã«ãŠã³ãåïŒä»»æïŒ
website: "" # Webãµã€ãïŒä»»æïŒ
ã€ãã³ãYAML ã§ã®ç»å£è ã®èšè¿°
talks:
- title: çºè¡šã¿ã€ãã«
speaker:
name: 衚瀺å # å¯èªæ§ã®ããã«æ®ã
id: speaker_id # speakers.yaml ã® id ãšäžèŽãããïŒå¿
é ïŒ
slide_url: ...
â» ãããã£ãŒã«æ å ±ïŒicon_url, twitter, github çïŒã¯ã€ãã³ãYAMLã«èšèŒããªãã
ãããã£ãŒã«æ å ±ã®åéæé
æ°ããç»å£è ã®æ å ±ã远å ããéã¯ã以äžã®é åºã§èª¿æ»ããïŒ
- connpass ã®ã€ãã³ãããŒãž â åå è äžèЧãã connpass ãŠãŒã¶ãŒåãç¹å®
- connpass ã®ãŠãŒã¶ãŒãããã£ãŒã«ïŒ
https://connpass.com/user/{username}/ïŒâ X, GitHub ãªã³ã¯ãååŸ - YouTube ã¢ãŒã«ã€ãåç»ã®æŠèŠæ¬ â ç»å£è åã»SNS ã¢ã«ãŠã³ãã®ç¢ºèª
- ç¹å®ã§ããªãå Žåã¯
idã«ä»®ã®å€ãèšå®ããæå確èªãå¿ èŠãªæšãã³ã¡ã³ãã§æ®ã
泚æäºé
-
icon_url㯠X ã connpass çããååŸããçŽæ¥URLãæ ŒçŽããïŒæåªå ã§äœ¿çšãããïŒ - ãã«ãæã«
icon_urlâgithubã®åªå åºŠã§æçµçãªã¢ã€ã³ã³URLãæ±ºãŸã - X / GitHub ã®ã¢ã€ã³ã³ã¯å€éšãµãŒãã¹çµç±ã®ãããããŒã«ã«ãã¡ã€ã«é²èЧæã¯è¡šç€ºãããªãå Žåããã
- ãããã£ãŒã«æ
å ±ã®å€æŽã¯
data/speakers.yamlã®ã¿ãç·šéããã°å šã€ãã³ãããŒãžã«åæ ããã
ããŒã«ã«ã§ã®ãµã€ãæ§ç¯
ãµã€ãã®åºæ¬æ§é
æåã®ã³ãããã§ã以äžã®ããŒãžæ§æã§äžæ°ã«æ§ç¯ããŸããã
- ãããããŒãž
- ã€ãã³ã詳现ããŒãž
- ç»å£è äžèЧããŒãž
- About ããŒãž
å
šã€ãã³ãåã®YAMLããŒã¿ãçšæãããã«ãã¹ã¯ãªããã§HTMLãçæãããŒã«ã«ã§ python -m http.server ã䜿ã£ãŠè¡šç€ºã確èªããªããéçºãé²ããŸããã
ãããããŒãžïŒã€ãã³ãäžèЧïŒ
å šã€ãã³ããã«ãŒã圢åŒã§æ°çé ã«äžèŠ§è¡šç€ºããããŒãžã§ãã

åã«ãŒãã«ã¯ã€ãã³ãçªå·ãã¿ã€ãã«ãé嬿¥ãçºè¡šæ°ãçºè¡šã¿ã€ãã«ã®ãã¬ãã¥ãŒã衚瀺ããŠããŸãã
幎床ãã£ã«ã¿ãŒãã¿ã³ã§è¡šç€ºãçµã蟌ããããã«ããŸãããJavaScript ã§ DOM ã®è¡šç€º/é衚瀺ãåãæ¿ãã軜éãªå®è£ ã§ãã
ã€ãã³ã詳现ããŒãž
ååã®è©³çްæ å ±ã衚瀺ããããŒãžã§ãã

äž»ãªèŠçŽ ãšããŠä»¥äžãå®è£ ããŸããã
- é嬿ŠèŠ: é嬿¥æãconnpassã€ãã³ãããŒãžã®ãªã³ã¯ã衚瀺
- YouTubeåç»åã蟌ã¿: é ä¿¡ã¢ãŒã«ã€ããããå Žåã«åç»ãã¬ã€ã€ãŒã衚瀺
- ã€ãã³ãã¬ããŒã: ã€ãã³ãã¬ãèšäºãããå Žåã¯ãªã³ã¯ãã¿ã³ã衚瀺
- çºè¡šã«ãŒã: ç»å£è ã®ã¢ã€ã³ã³ã»ååã»SNSãªã³ã¯ãçºè¡šã¿ã€ãã«ãã¿ã°ã衚瀺
- åç»åçç®æã®ãªã³ã¯: åçºè¡šã®éå§æéãžã®ãªã³ã¯ãçæ
- ã¹ã©ã€ãåã蟌ã¿: çºè¡šè³æãããŒãžå ã§çŽæ¥é²èЧå¯èœïŒiframeïŒ
- é¢é£ãªã³ã¯: ã¹ã©ã€ãURLã»é¢é£èšäºãããå Žåã¯ãªã³ã¯ãã¿ã³ã衚瀺

ç»å£è
ã®ãããã£ãŒã«æ
å ±ã¯ data/speakers.yaml ã§äžå
管çããŠããããã«ãæã«ã€ãã³ãYAMLã® speaker.id ãšããŒãžãããŸããããã«ããããããã£ãŒã«ã®å€æŽã¯ speakers.yaml ãç·šéããã ãã§å
šã€ãã³ãããŒãžã«åæ ãããŸãã
# data/speakers.yaml
- id: unsoluble_sugar
name: æåœ±
icon_url: https://github.com/unsolublesugar.png
twitter: unsoluble_sugar
github: unsolublesugar
zenn: unsoluble_sugar
website: https://linktr.ee/unsoluble_sugar
ã¹ã©ã€ãåã蟌ã¿ã®èªåçæ
çºè¡šè³æã¯ Speaker DeckãGoogle SlidesãDocswell ãªã©æ§ã
ãªãµãŒãã¹ã䜿ãããŠããŸããYAMLã« slide_urlïŒé²èЧçšURLïŒãèšèŒããã ãã§ããã«ãæã«åãµãŒãã¹ã®åã蟌ã¿URLãèªåçæããããã«ããŸããã
def generate_slide_embed_url(slide_url: str, sd_cache: dict) -> str:
# Google Slides
if "docs.google.com/presentation" in slide_url:
m = re.search(r"/d/([a-zA-Z0-9_-]+)", slide_url)
if m:
return f"https://docs.google.com/presentation/d/{m.group(1)}/embed"
# SlideShareïŒsecretãªã³ã¯ã¯ã¹ãããïŒ
if "slideshare.net/" in slide_url and "/secret/" not in slide_url:
slug = slide_url.split("?")[0].rstrip("/").split("/")[-1]
return f"https://www.slideshare.net/slideshow/{slug}/embed"
# Docswell
if "docswell.com/s/" in slide_url:
after_s = slide_url.split("/s/")[1]
parts = after_s.split("/")
if len(parts) >= 2:
slug_full = parts[1].split("#")[0]
slug = slug_full.split("-")[0] # æ¥ä»ãµãã£ãã¯ã¹é€å»
return f"https://www.docswell.com/slide/{slug}/embed"
# slides.com
if "slides.com/" in slide_url and "/embed" not in slide_url:
clean = slide_url.split("?")[0].split("#")[0].rstrip("/")
return clean + "/embed"
# Speaker DeckïŒoEmbed APIçµç±ïŒ
if "speakerdeck.com/" in slide_url:
return _fetch_speakerdeck_embed(slide_url, sd_cache)
return ""
Google Slidesã»Docswellã»slides.com 㯠URL ã®ãã¿ãŒã³ãããã§åã蟌ã¿URLãçµã¿ç«ãŠãŠããŸããSpeaker Deck 㯠oEmbed API ãåŒã³åºããŠiframeã®src URLãååŸããæ¹åŒã§ããAPIåŒã³åºãã®çµæã¯ãã£ãã·ã¥ããŠãããæ¬¡å以éã®ãã«ãã§ã¯åååŸããªãããã«ããŠããŸãã
ç»å£è äžèЧããŒãž
éå»ã«ç»å£ããã ããæ¹ã ã®ãããã£ãŒã«ãšç»å£å±¥æŽããŸãšããããŒãžã§ãã

- æ€çŽ¢ããã¯ã¹: ååãIDã§ãªã¢ã«ã¿ã€ã æ€çŽ¢
- ãœãŒãåæ¿: ç»å£åæ°é / ææ°ã€ãã³ãé / ååé ããã¿ã³ã§åãæ¿ã
- ç»å£è ã«ãŒã: ã¢ã€ã³ã³ãååãSNSãªã³ã¯ïŒX, GitHub, Qiita, ZennçïŒãç»å£åæ°ãçºè¡šå±¥æŽã®äžèЧã衚瀺
ã¢ã€ã³ã³ç»å㯠speakers.yaml ã® icon_url ãã£ãŒã«ããæåªå
ãšããæªèšå®ã®å Žå㯠GitHub ã¢ãã¿ãŒïŒhttps://github.com/{username}.pngïŒã«ãã©ãŒã«ããã¯ããä»çµã¿ã§ãã
About ããŒãž
ã³ãã¥ããã£ã®ç޹ä»ãçµ±èšæ å ±ïŒã€ãã³ãé嬿°ãLTçºè¡šæ°ãç»å£è æ°ïŒãéå¶ã¡ã³ããŒãåå æ¹æ³ãªã©ããŸãšããããŒãžã§ãã


çµ±èšæ å ±ã¯ãã«ãæã«YAMLããŒã¿ããèªåéèšãããŸãã

GitHub Pages ãžã®ãããã€
ããŒã«ã«ã§ã®åäœç¢ºèªãããçšåºŠæžãã æ®µéã§ãGitHub ãªããžããªã«ããã·ã¥ããGitHub Pages ã§ã®å ¬éã«ç§»ããŸãããGitHub Pages ã®åºæ¬çãªä»çµã¿ãåæèšå®ã«ã€ããŠã¯ãå ¬åŒããã¥ã¡ã³ããåç §ããŠãã ããã
GitHub Pages ã®æºå
ãªããžããªã® Settings â Pages ããããœãŒã¹ããGitHub Actionsãã«èšå®ããŸãã

ãã©ã³ãæå®æ¹åŒïŒgh-pages ãã©ã³ãçïŒã ãšããã«ãææç©ããªããžããªã«ã³ãããããå¿
èŠããããŸãããActions ã¯ãŒã¯ãããŒããã®çŽæ¥ãããã€ã§ããã°ããã«ãææç©ãgit管çããã«æžã¿ãpushãããªã¬ãŒã«ãã«ããããããã€ãŸã§äžæ°é貫ã§å®è¡ã§ããŸãã
GitHub Actions ã¯ãŒã¯ãããŒ
main ãã©ã³ããžã®ããã·ã¥ãããªã¬ãŒã«ããã«ããšãããã€ãèªåã§å®è¡ãããŸããã¯ãŒã¯ãããŒã®å
容ã¯ã·ã³ãã«ã§ãPython ã®ã»ããã¢ãã â äŸåããã±ãŒãžã®ã€ã³ã¹ããŒã« â build.py ã®å®è¡ â output/ ãã£ã¬ã¯ããªã GitHub Pages ã«ã¢ããããŒãããšããæµãã§ãã
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: 'pip'
- run: pip install -r requirements.txt
- run: cd src && python build.py
- uses: actions/upload-pages-artifact@v3
with:
path: output
deploy:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/deploy-pages@v4
ãããã€ããŠè¡šç€ºç¢ºèª
ååããã·ã¥åŸãGitHub Actions ã®ãã«ããæåãããš https://ãŠãŒã¶ãŒå.github.io/ãªããžããªå/ ã§ãµã€ããå
¬éãããŸãã以é㯠Claude Code ã§ã³ãããïŒããã·ã¥ãŸã§äžæ°ã«æç€ºã§ããã®ã§ãä¿®æ£âãããã€â確èªã®ãµã€ã¯ã«ãæ°åç§åäœã§åããããã«ãªããŸããã
ã€ãã³ãããŒã¿ã®å°éãªä¿®æ£
åæããŒã¿ã®åé㯠Claude Code ã«ä»»ããŠããã®ã§ãããæ å ±ãœãŒã¹ãšãªãWebããŒãžã«ãã£ãŠã¯ Web fetch ã§ããŒãžå šäœãååŸããããããŒã¿ãæ¬ èœããã±ãŒã¹ããããŸããã
ãŸããconnpass ã YouTube ã®æŠèŠæ¬ã«ããããèšèŒãããŠããªãæ å ±ïŒã¹ã©ã€ãURLãçºè¡šè ã®SNSã¢ã«ãŠã³ãçïŒãå€ããçµæãšããŠããªãã®éã®æå確èªã»ä¿®æ£ãå¿ èŠã«ãªããŸããã
å ·äœçã«ã¯ä»¥äžã®ãããªä¿®æ£ãè¡ã£ãŠããŸãã
- connpassã€ãã³ãããŒãžURL â è€æ°ååã§ééã£ãURLãèšå®ãããŠããããä¿®æ£
- ç»å£è ã®å²ãåœãŠãã¹ â çºè¡šè ã®åãéããè€æ°ä»¶ããä¿®æ£
- çºè¡šé ã®ä¿®æ£ â YouTubeåç»ã®åçé ãšäžèŽããããã«äžŠã¹æ¿ã
- YouTube ã¿ã€ã ã¹ã¿ã³ãã®è¿œå â æ¬ èœããŠããçºè¡šéå§æéãåç»ãã確èªããŠè£å®
- ç»å£è ã®è¡šç€ºåå€æŽ â connpassåããã®å€æŽåžæã«å¯Ÿå¿
- ã¹ã©ã€ãURLã®è¿œå â ãªã³ã¯ãæ¬ èœããŠããçºè¡šã«è³æURLã远å
ãšã¯ãããä¿®æ£äœæ¥èªäœã¯ Claude Code ã«ã#28ã®ã¿ã€ã ã¹ã¿ã³ãã远å ããŠãã®ããã«æç€ºãããšãYAMLã®ç·šéã»ãªãã«ãã»ç¢ºèªãŸã§ãäžæ°ã«é²ããŠãããã®ã§ã人éãããã®ã¯ãæ£ããæ å ±ã®ç¢ºèªãã«éäžã§ããŸããã
å ¬éåŸã®æ¹å
ãããã€ããŠå®éã®ãã©ãŠã¶ã§ç¢ºèªãããšãããŒã«ã«ã§ã¯æ°ã¥ããªãã£ãåé¡ãããã€ãèŠã€ãããŸãããå ¬éåŸã«è¡ã£ãæ¹åã¯ä»¥äžã®éãã§ãã
- YouTubeåã蟌ã¿åçã®å®è£ ãšä¿®æ£
- ã¬ã¹ãã³ã·ããã¶ã€ã³å¯Ÿå¿
- ã€ãã³ãäžèЧã®äœ¿ãåææ¹å
- ç»å£è äžèŠ§ã®æ¹å
- ããã¿ãŒã»OGPã»ã¡ã¿æ å ±ã®æŽå
- äŒç»ã³ãŒããŒããŒãžã®æ°èš
- ç»å£è åå¥ããŒãžã®è¿œå
ããããã®è©³çްãé ã«ç޹ä»ããŸãã
YouTubeåã蟌ã¿åçã®å®è£ ãšä¿®æ£
ã€ãã³ã詳现ããŒãžã§ã¯ãYouTubeåç»ã®ãµã ãã€ã«ãã¯ãªãã¯ãããš iframe åã蟌ã¿ãã¬ãŒã€ãŒã«åãæ¿ãããããŒãžå
ã§çŽæ¥åçã§ããæ©èœãå®è£
ããŸãããããŒã«ã«ç°å¢ïŒfile://ïŒã§ã¯ YouTube ããŒãžãæ°ããã¿ãã§éãåäœã«ããŠããŸãã

ãšãããããããã€åŸã«å
¬éããŒãžã§ãµã ãã€ã«ãã¯ãªãã¯ããŠãäœãåå¿ããªããšããåé¡ãçºçããŸãããåå ã調æ»ãããšããããã³ãã¬ãŒãã§ <a> ã¿ã°ã <div> ã¿ã°ã«å€æŽããããšã§ãã¯ãªãã¯åäœãJavaScriptã®ã€ãã³ããã³ãã©ã«å®å
šäŸåããæ§é ã«ãªã£ãŠããããšãããããŸããããã©ãŠã¶ãã£ãã·ã¥ã§æ§JSãæ®ã£ãŠããå ŽåããJSèªã¿èŸŒã¿å€±ææã«ãªã³ã¯ãç¡åå¿ã«ãªãåé¡ããããŸããã
ä¿®æ£ãšã㊠<a> ã¿ã°ããŒã¹ã«æ»ããJavaScript ã§ preventDefault() ããŠãã iframe ã«å·®ãæ¿ããå®è£
ã«å€æŽããŸãããããã«ãããJS ãç¡å¹ã§ã YouTube ãžã®ãªã³ã¯ãšããŠæ©èœããããã°ã¬ãã·ããšã³ãã³ã¹ã¡ã³ãã確ä¿ã§ããŸããã
function initYouTubePlayer() {
const players = document.querySelectorAll('.youtube-player-wrapper');
if (!players.length) return;
const isLocal = window.location.protocol === 'file:';
if (isLocal) return; // ããŒã«ã«ã§ã¯<a>ã¿ã°ã®ããã©ã«ãåäœã«ä»»ãã
players.forEach(wrapper => {
const videoId = wrapper.dataset.videoId;
if (!videoId) return;
wrapper.addEventListener('click', (e) => {
e.preventDefault();
// å
¬éããŒãžã§ã¯iframeåã蟌ã¿ã«å·®ãæ¿ã
const iframe = document.createElement('iframe');
iframe.src = 'https://www.youtube-nocookie.com/embed/'
+ videoId + '?autoplay=1&rel=0';
iframe.setAttribute('allow',
'accelerometer; autoplay; clipboard-write; '
+ 'encrypted-media; gyroscope; picture-in-picture');
iframe.setAttribute('allowfullscreen', '');
iframe.className = 'youtube-iframe';
wrapper.innerHTML = '';
wrapper.appendChild(iframe);
});
});
}
ã¬ã¹ãã³ã·ããã¶ã€ã³å¯Ÿå¿
PCã§ã®è¡šç€ºãäžå¿ã«æ§ç¯ãé²ããŠããã®ã§ãã¹ããã§å®éã«ã¢ã¯ã»ã¹ããŠã¿ããšã¢ãã€ã«èæ ®ã®äžè¶³ã«ãã厩ããè€æ°èŠã€ãããŸããã
äž»ãªåé¡ãšå¯Ÿå¿ã¯ä»¥äžã®éãã§ãã
- ããããŒ: ããã²ãŒã·ã§ã³ã®ããã¹ããæãè¿ããŠäºæ®µã«ãªã£ãŠããããããåå ããããã¿ã³ãããããŒããé衚瀺ã«ãã代ããã«ãããããŒãžã®ããŒããŒã»ã¯ã·ã§ã³ã«å€§ããã®ãã¿ã³ãšããŠé 眮
-
ã€ãã³ãã«ãŒã: çºè¡šã¿ã€ãã«ã®
white-space: nowrapã flexbox ã®min-width: autoãšçµã¿åããããã«ãŒãå¹ ãæŒãåºããŠæšªã¹ã¯ããŒã«ãçºçãmin-width: 0ãšoverflow: hiddenã§è§£æ±º -
ç»å£è
ã«ãŒã: çºè¡šå±¥æŽã®ã#çªå·ã»ã¿ã€ãã«ã»æ¥ä»ããæšªäžåã«éå»¶ã³ããŠãããããCSS
orderã§ã#çªå· æ¥ä» / ã¿ã€ãã«å šå¹ ãã®2è¡ã¬ã€ã¢ãŠãã«å€æŽ - ããã¿ãŒ: ã³ããŒã©ã€ã衚瀺ãäžå€®å¯ãã«
- ããŒããŒçµ±èšã«ãŒã: 3ã«ãŒãã®ãã¡éå¬ã¹ã±ãžã¥ãŒã«ã®ã¿è¡šç€ºããçã¹ããŒã¹å
flexbox ã CSS Grid ã䜿ã£ãã¬ã€ã¢ãŠãã§ã¯ãPC衚瀺ã§åé¡ãªããŠãã¢ãã€ã«ã§æå³ããªãæåã«ãªãã±ãŒã¹ãããã®ã§ãã¡ãã£ã¢ã¯ãšãªã§ã®èª¿æŽã¯æ¬ ãããŸããã§ããã

ã€ãã³ãäžèЧã®äœ¿ãåææ¹å
éå»ã®ã€ãã³ãããã¹ãŠè¡šç€ºããããšã¹ã¯ããŒã«éãèšå€§ã«ãªããããããã©ã«ã衚瀺ãçŸåšå¹Žã®ã€ãã³ãã®ã¿ã«å€æŽããŸãããããã¹ãŠããã£ã«ã¿ãŒã¯æåŸã«é 眮ããéžææã¯12ä»¶ãã€ã®ãããã«èªã¿èŸŒããããŒãžããŒã·ã§ã³ãå°å ¥ããŠããŸãã


幎ãã£ã«ã¿ãŒéžææã«ã¯ãäžèЧäžéšã«ãâ 2025幎ãã2024幎 âãã®ãããªããã²ãŒã·ã§ã³ãã¿ã³ãé 眮ããŸã éå¬ãããŠããªãã€ãã³ãã®ã«ãŒãã«ã¯ãéå¬äºå®ããããžãšãåå è ã»ç»å£è åéäžïŒãã®ã¡ãã»ãŒãžã衚瀺ããããã«ããŸããã

ã€ãã³ã詳现ããŒãžã«ããããŒãžäžéšã«ååŸã®ã€ãã³ããžã®ããã²ãŒã·ã§ã³ãã¿ã³ãé 眮ããŠããŸããäžå€®ã«ã€ãã³ãäžèЧãžã®ãªã³ã¯ãå·Šå³ã«ååŸã®ã€ãã³ããšãã3ãã¿ã³æ§æã§ãã

ç»å£è äžèŠ§ã®æ¹å
ç»å£åæ°ã®å€ããŠãŒã¶ãŒã®è¡šç€ºé åã倧ãããªããããåé¡ããHTML ã® <details> / <summary> èŠçŽ ã§è§£æ±ºããŸãããææ°3ä»¶ãåžžæè¡šç€ºãã4件以äžã¯ãä» Nä»¶ã®çºè¡šãèŠããã§å±éãå±éåŸã¯ãéãããã«åãæ¿ãããŸãã

æ€çŽ¢æ©èœãæ¡å ããååãIDã ãã§ãªãçºè¡šã¿ã€ãã«ã§ãããããããã察å¿ããŸããããããããããŒã¯ãŒãããã€ã©ã€ã衚瀺ããæ©èœã远å ããŠããŸãã

ããã¿ãŒã»OGPã»ã¡ã¿æ å ±ã®æŽå
ããã¿ãŒã®ããã¹ããªã³ã¯ãæŽçããconnpassïŒã³ãã¥ããã£ïŒãš YouTubeïŒãã£ã³ãã«ç»é²ïŒã®2ã€ã«çµã£ãŠSVGã¢ã€ã³ã³ä»ããã¿ã³ã«å€æŽããŸããã

YouTubeã®ãªã³ã¯ã«ã¯ ?sub_confirmation=1 ãã©ã¡ãŒã¿ãä»ããŠããã£ã³ãã«ç»é²ç¢ºèªãã€ã¢ãã°ã«çŽæ¥é·ç§»ããããã«ããŠããŸãã
ãŸããOpen Graph Protocol ãš Twitter Card ã®ã¡ã¿ã¿ã°ãå šããŒãžã«è¿œå ããSNSã·ã§ã¢æã®ãã¬ãã¥ãŒè¡šç€ºã«ã察å¿ããŸãããOGç»åã¯1200Ã630pxã§çšæããŠããŸãã
<!-- OGP -->
<meta property="og:title" content="{{ site_title }}">
<meta property="og:description" content="{{ site_description }}">
<meta property="og:type" content="website">
<meta property="og:url" content="{{ site_url }}">
<meta property="og:site_name" content="{{ site_title }}">
<meta property="og:image" content="{{ site_og_image }}">
<meta property="og:locale" content="ja_JP">
<!-- Twitter Card -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="{{ site_title }}">
<meta name="twitter:description" content="{{ site_description }}">
<meta name="twitter:image" content="{{ site_og_image }}">
site_title ã site_url çã®å€ã¯ãã«ãæã«èšå®ãã¡ã€ã«ïŒsrc/config/settings.pyïŒããæ³šå
¥ãããã®ã§ããã³ãã¬ãŒãåŽã¯Jinja2ã®å€æ°ãåç
§ããã ãã§ãã
äŒç»ã³ãŒããŒããŒãžã®æ°èš
ã€ãã³ãå ã§å®æœããŠããããã£ã¬ã³ãžã³ãŒããŒãããã¡ããã£ãšæ·±å ãããšãã£ãç¹å¥äŒç»ã®ã¢ãŒã«ã€ãããŒãžãæ°èšããŸããã

ããŒã¿ç®¡çã®å·¥å€«
äŒç»ã³ãŒããŒã®çºè¡šã¯å人ã®ç»å£ã§ã¯ãªãéå¶ã¡ã³ããŒãåå è
å
šå¡ã§è¡ããã®ãªã®ã§ãspeaker.id = "easy2" ãšããç¹å¥ãªIDãå²ãåœãŠãŸããããã«ãã¹ã¯ãªããã§ easy2 ãç»å£è
äžèЧããé€å€ãã€ã€ãäŒç»ããŒãžã«ã®ã¿è¡šç€ºããä»çµã¿ã§ãã

ã¿ã€ãã«ã«ããã£ã¬ã³ãžã³ãŒããŒããå«ããã®ã¯ãã£ã¬ã³ãžã»ã¯ã·ã§ã³ã«ããã以å€ïŒã¡ããã£ãšæ·±å ããsli.doããŒã¯ã¿ã€ã çïŒã¯æ·±å ãã»ã¯ã·ã§ã³ã«èªåæ¯ãåãããŠããŸãã
çªå€ç·šäŒç»ã®ããŒã¿è¿œå
åè¿°ã®äŒç»ã³ãŒããŒã¯éåžžã®LTçºè¡šãšã¯å¥æ ã§å®æœãããŠãããããæ¢åã®ã€ãã³ãããŒã¿ã«ã¯å«ãŸããŠããŸããã§ãããéå»ã®åç»ãèŠè¿ããªãã該åœããåã®æ å ±ããŸãšããŠè¿œå ããŠããŸãã倧éã®YAMLãã¡ã€ã«ãå¹ççã«æŽæ°ãããããPythonã¹ã¯ãªããã§äžæ¬åŠçããŸããã
ç»å£è åå¥ããŒãžã®è¿œå
ãµã€ãå ¬éåŸã«äžéãè§Šã£ãŠãããšããããâ¯â¯ããããããŸã§çºè¡šããå 容ãäžèЧã§èŠããããšããèŠæãžã®èæ ®æŒãã«æ°ã¥ããŸãããç»å£è äžèЧããŒãžã§ã¯çºè¡šã¿ã€ãã«ãŸã§ã¯ç¢ºèªã§ããŸãããå®éã«è³æãåç»ã蟿ãã«ã¯ã€ãã³ã詳现ããŒãžãžé£ã¶å¿ èŠããããç»å£åæ°ã®å€ãæ¹ã»ã©æãäžããäžäŸ¿ãªæ§é ã§ããã
ããã§ãç»å£è
ããšã®åå¥ããŒãž /speakers/{speaker_id}/ ãæ°èšããŸããã

ããŒãžæ§æ
- ããããŒ: ã¢ã€ã³ã³ïŒå€§ãµã€ãºïŒãååãç»å£åæ°ãSNSãªã³ã¯
- çºè¡šå±¥æŽã«ãŒã: é嬿¥ã®éé ã§äžŠã¶ãåã«ãŒãã«ã¯ã€ãã³ãçªå·ã»é嬿¥ã»ã¿ã€ãã«ã»ã¿ã°ã»ãªã³ã¯ãã¿ã³çŸ€ïŒã€ãã³ã詳现 / ã¹ã©ã€ã / åç» / é¢é£èšäºïŒã衚瀺
- äžéš: ãç»å£è äžèŠ§ã«æ»ãããã¿ã³
ãã®ããŒãžã§ã¯äžèЧæ§ãéèŠããŠãåç»ãã¹ã©ã€ãã®åã蟌ã¿ïŒiframeïŒã¯ãããŠäœ¿ãããã·ã³ãã«ãªãªã³ã¯ãã¿ã³åœ¢åŒã«ããŠããŸããç»å£åæ°ãå€ãæ¹ã®ããŒãžã§ã衚瀺ã軜éã«ãªããçºè¡šã俯ç°ãããããªããŸããã
æ¢åããŒãžããã®å°ç·
ç»å£è
äžèЧããŒãžã®åã«ãŒããããã³ã€ãã³ã詳现ããŒãžã®çºè¡šã«ãŒããããç»å£è
ã¢ã€ã³ã³ã»ååãã¯ãªãã¯ãããšåå¥ããŒãžãžé·ç§»ã§ããããã«ããŸããããã ã speaker.id ã tbdïŒçºè¡šè
æªå®ïŒã easy2ïŒã³ãã¥ããã£äŒç»æ ïŒã®å Žåã¯ãªã³ã¯ã«ããªãæ¡ä»¶åå²ãå
¥ããŠããŸãã
{% set has_speaker_page = talk.speaker.id not in ('tbd', 'easy2') %}
ãã«ãåŠçã®æ¡åŒµ
ç»å£è
ããšã«åå¥ããŒãžãåºåããã«ãŒãã build.py ã«è¿œå ããŸãããã¯ãªãŒã³URL察å¿ãšã㊠output/speakers/{id}/index.html ã®æ§é ã§åºåããéå±€ãæ·±ããªãå base_path 㯠"../.." ãæå®ããŠããŸãã
tpl = env.get_template("speaker_detail.html")
for speaker in speakers:
speaker_dir = speakers_dir / speaker["id"]
speaker_dir.mkdir(exist_ok=True)
html = tpl.render(
speaker=speaker,
base_path="../..",
**{k: v for k, v in common_ctx.items() if k != "base_path"},
)
(speaker_dir / "index.html").write_text(html, encoding="utf-8")
ã€ãã³ã詳现ããŒãžããæ°ã«ãªãç»å£è ã®ã¢ã€ã³ã³ãã¿ããããŠããã®äººã®ä»ã®çºè¡šã«é£ã¹ãå°ç·ãã§ããããšã§ããµã€ãå ã®åéæ§ã倧ããäžãããŸããã
ã¯ãªãŒã³URL察å¿
/about.html ã§ã¯ãªã /about ã§ã¢ã¯ã»ã¹ã§ããããããã£ã¬ã¯ããªããŒã¹ã®åºåæ§é ã«å€æŽããŸãããNext.js ã Hugo ãªã©ã®ãã¬ãŒã ã¯ãŒã¯ã䜿ã£ãŠããã°ããã©ã«ãã§å¯Ÿå¿ãããŠããéšåã§ãããä»åã¯çŽ ã®Python + Jinja2 ã§æ§ç¯ããŠããããèªåã§å¯Ÿå¿ããå¿
èŠããããŸããã
# Before
output/about.html
output/events/075.html
# After
output/about/index.html
output/events/075/index.html
ãã«ãã¹ã¯ãªããã®åºåå
ãš base_pathïŒçžå¯Ÿãã¹ïŒã®èª¿æŽã§å¯Ÿå¿ããŠããŸãããã³ãã¬ãŒãå
ã®ãªã³ã¯ãã .html æ¡åŒµåãé€å»ããã ãã§ãªããåããŒãžã®éå±€ã«å¿ãã base_path ãæ£ããèšå®ããå¿
èŠããããŸããã
ã«ã¹ã¿ã ãã¡ã€ã³ã®èšå®
GitHub Pages ã®ããã©ã«ãã®ãŸãŸå
¬éãããšãURLã https://ãŠãŒã¶ãŒå.github.io/ãªããžããªå/ ã®ããã«ãªããŸããã³ãã¥ããã£ã®ãµã€ããªã®ã«äœè
å人ã®ååãURLã«å«ãŸããã®ã¯å°ã
ãããããªãã®ã§ãã«ã¹ã¿ã ãã¡ã€ã³ãèšå®ããããšã«ããŸããã
ååŸãããã¡ã€ã³ã¯ easy2.jp ã§ããeasy2 ã®ãããªçãæ±çšæ§ã®é«ããã¡ã€ã³åã¯ãã§ã«ååŸæžã¿ã§ããããšãå€ããeasy2.com / easy2.net / easy2.org ãªã©ã®äž»èŠTLDã¯ããããä»æã§æŒãããããŠããŸããããããªäžã§ .jp ãå¯äžç©ºããŠãããšããã®ã¯å¹žéã§ããã
ã³ãã¥ããã£åãã®ãŸãŸã®ãã¡ã€ã³ãåããã®ã¯çšãªã®ã§ã欲ãããã¡ã€ã³ãããã°æ©ãã«ç¢ºä¿ããŠããã®ããã¹ãã§ãã
ãªãããã¡ã€ã³ã®ååŸã«ã¯ XServer Domain ãå©çšããŸããã
çè ãæ®æ®µããäœ¿ãæ £ããŠãããšããçç±ã§æ¡çšããŠããŸãããç¹ã«ãã ãããããããã§ã¯ãªãã®ã§ãçããã奜ããªãã¡ã€ã³ãµãŒãã¹ã§ååŸããã°OKã§ãã
ããŒã ãµãŒããŒã®èšå®
æåã®ããããã€ã³ããããŒã ãµãŒããŒã®èšå®ã§ãããXServer Domain ã®ããŒã ãµãŒããŒã¯ä»¥äžã䜿çšããŸãã
| çªå· | ããŒã ãµãŒã㌠|
|---|---|
| 1 | ns1.xdomain.ne.jp |
| 2 | ns2.xdomain.ne.jp |
| 3 | ns3.xdomain.ne.jp |
åœå ns1.xserver.jpïŒã¬ã³ã¿ã«ãµãŒããŒçšïŒãèšå®ããŠããŸããDNS ã¯ãšãªã REFUSED ã«ãªã£ãŠå
šã解決ã§ããªãç¶æ
ã«ãXServer Domain åäœã§ DNS ã䜿ãå Žå㯠xdomain.ne.jp ã®ããŒã ãµãŒããŒãæå®ããå¿
èŠããããŸãã

DNSã¬ã³ãŒãã®èšå®
ç¶ã㊠XServer Domain ã® DNS ã¬ã³ãŒãèšå®ã§ã以äžã®ã¬ã³ãŒãã远å ããŸããã
Aã¬ã³ãŒãïŒIPv4ïŒ â GitHub Pages ã®IPã¢ãã¬ã¹4ã€:
| ãã¹ãå | çš®å¥ | å 容 | TTL |
|---|---|---|---|
| @ | A | 185.199.108.153 |
3600 |
| @ | A | 185.199.109.153 |
3600 |
| @ | A | 185.199.110.153 |
3600 |
| @ | A | 185.199.111.153 |
3600 |
AAAAã¬ã³ãŒãïŒIPv6ïŒ:
| ãã¹ãå | çš®å¥ | å 容 | TTL |
|---|---|---|---|
| @ | AAAA | 2606:50c0:8000::153 |
3600 |
| @ | AAAA | 2606:50c0:8001::153 |
3600 |
| @ | AAAA | 2606:50c0:8002::153 |
3600 |
| @ | AAAA | 2606:50c0:8003::153 |
3600 |
CNAMEã¬ã³ãŒã â www ãµããã¡ã€ã³çš:
| ãã¹ãå | çš®å¥ | å 容 | TTL |
|---|---|---|---|
| www | CNAME | unsolublesugar.github.io |
3600 |
CNAMEã¬ã³ãŒãã¯ãwww.easy2.jp ã®ãããªãµããã¡ã€ã³ãžã®ã¢ã¯ã»ã¹ã GitHub Pages ã®ããã©ã«ããã¡ã€ã³ïŒ{ãŠãŒã¶ãŒå}.github.ioïŒãžè»¢éããããã«èšå®ããŸãã
ããã«ãããeasy2.jp ãš www.easy2.jp ã®äž¡æ¹ãããµã€ãã«ã¢ã¯ã»ã¹ã§ããããã«ãªããŸããGitHub Pages åŽã§ã¯èªåçã«æ£èŠã®ãã¡ã€ã³ãžãªãã€ã¬ã¯ããããŸãã
ãã¡ã€ã³æææš©ã®æ€èšŒ
ãã©ãã«ã·ã¥ãŒãã®äžç°ãšããŠãGitHub ã® Settings â Pages â Verified & approved domains ã§ easy2.jp ã远å ãã衚瀺ããã TXT ã¬ã³ãŒãã XServer Domain ã® DNS ã«è¿œå ããŸããã
| ãã¹ãå | çš®å¥ | å 容 |
|---|---|---|
_github-pages-challenge-unsolublesugar |
TXT | ïŒGitHub ã衚瀺ããæ€èšŒçšã®å€ïŒ |
ãã¡ã€ã³æææš©ã®æ€èšŒã¯ãä»ãŠãŒã¶ãŒã«ãããã¡ã€ã³ä¹ã£åããé²ãããã®ã»ãã¥ãªãã£æ©èœã§ããCustom domain ã®èšå®ä¿åèªäœã¯ãã¡ã€ã³æ€èšŒãªãã§ãã§ãããã®ã®ãDNS check ã®ãšããã§èµ€ã à ãåºç¶ããããã䜵ããŠãã¡ãã察å¿ããŸããã
DNSåæ ã®åŸ ã¡æé
DNS ã¬ã³ãŒãã®èšå®èªäœã¯æ°åã§æš©åšããŒã ãµãŒããŒã«åæ ãããŸããããå DNS ãµãŒããŒãžã®äŒæã«ã¯æéå·®ããããŸããã

dig ã³ãã³ãã§ Google DNSïŒ8.8.8.8ïŒããã¯åŒããã®ã«ãããŒã«ã«ã® ISP DNS ã§ã¯ãŸã SERVFAIL ãè¿ããªã©ãç°å¢ã«ãã£ãŠã¢ã¯ã»ã¹ã§ãããã§ããªãã£ãããšããç¶æ
ãç¶ããŸããã
# æš©åšNSã§ç¢ºèªïŒããåæ ãããïŒ
dig easy2.jp A @ns1.xdomain.ne.jp +short
# Google DNS ã§ç¢ºèªïŒæ°åãæ°æéã§åæ ïŒ
dig easy2.jp A @8.8.8.8 +short
# ããŒã«ã«DNSãã£ãã·ã¥ãã¯ãªã¢ïŒMacïŒ
sudo dscacheutil -flushcache && sudo killall -HUP mDNSResponder
ãã®DNSã¬ã³ãŒãã®åæ ã«ãããæéã¯ãéåžžæ°æéãæå€§72æéãšèšãããŠããŸãã
ä»åã®å Žåã¯äžžäžæ¥ããããŸããããã®éãããªã«ãå¯Ÿå¿æŒãããªããããèšå®ãã¹ããªããããªã©ãæ¶ã ãšããæéãéããããã§ããâŠã§ããããšã¯ãã ç¥ã£ãŠåŸ ã€ã ãã§ãã
GitHub Pages åŽã®èšå®
DNS ãåæ ãããåŸãGitHub Pages ã®èšå®ç»é¢ã§ Custom domain ã« easy2.jp ãå
¥åããŠä¿åããŸããDNS check ãéããš HTTPS èšŒææžãèªåçºè¡ããããEnforce HTTPSããæå¹ã«ã§ããŸãã

æ£åŒãªãªãŒã¹
DNSãç¡äºã«åæ ãããåŸã¯ãGitHub Pages åŽã® DNS check ãééããHTTPSèšŒææžïŒLet's EncryptïŒãèªåçºè¡ãããŸãããHTTPSã§ã®ã¢ã¯ã»ã¹ãSSLèšŒææžã®æå¹æ§ããªãã€ã¬ã¯ãåäœãªã©è«žã ã®ãã§ãã¯ãéã£ãããšã確èªããæŽããŠæ£åŒãªãªãŒã¹ãè¿ããããšãã§ããŸããã
åèãªã³ã¯
ãããã«
Claude Code ãšã®å¯Ÿè©±ããŒã¹ã§ã®éçºã¯ãç¹ã«ãããããããŒã¿æŽå + UIæ¹åãã®ç¹°ãè¿ããå€ããããžã§ã¯ããšã®çžæ§ãè¯ããšæããŸãããä»åã®ãããªå°èŠæš¡ãªéçãµã€ãã§ããã°ã鱿«2æ¥ããã°ãªãªãŒã¹ãŸã§æŒãçããããŸããããããããšãèšèã§äŒããã°åœ¢ã«ããŠãããã®ã§ãã³ãŒãã£ã³ã°çµéšãå°ãªãæ¹ã«ãããããã§ããŸãã
äžæ¹ã§ã倧éããŒã¿ã®äžæ¬å€æŽæã«æå³ããªãäžæžããçºçããã±ãŒã¹ããããgit diff ã§ã®å·®å確èªã¯æ¬ ãããŸããããŸããçæãããUI/UXã¯å®éã«ãã©ãŠã¶ãã¹ããã§è§Šã£ãŠã¿ããšæ°ã«ãªãç¹ãåºãŠãããã®ã§ããClaude Code ã«ä»»ãã£ããã«ãããèªåã®ç®ã§ç¢ºèªããŠæ¹åã®ãã£ãŒãããã¯ãéããããšããå®æåºŠãäžãããã€ã³ãã ãšæããŸããã
ä»åã®éçºã«ããããããŸã§èª²é¡ã«æããŠããéšåã¯æŠãæºãããŸãããéå»ã®çºè¡šè³æã暪æçã«æ¢ããããŒã¿ã«ãšããŠãä»åŸã®ã³ãã¥ããã£ã®æŽ»åèšé²ã«åœ¹ç«ãŠãŠãããã°ãšæããŸãã
ãªããä»ã®ã³ãã¥ããã£ã§ãåæ§ã®ããŒã¿ã«ãµã€ããäœãããããä»åã®æ§æããã³ãã¬ãŒãåãããªããžããªãå ¬éããŠããŸãããµã€ããèŠãŠããã£ãŠãè¯ããªïŒããšæã£ãæ¹ã¯ãèªèº«ã®ã³ãã¥ããã£ã«åã£ã圢ã«ã«ã¹ã¿ãã€ãºããŠãã²æŽ»çšããŠã¿ãŠãã ããã
Easy Easy ã¯ãšã³ãžãã¢ãªã³ã°ãæããå šãŠã®äººã®çºã®ã³ãã¥ããã£ã§ãïŒ ææ°æè¡ã倧äºã§ããããã®ã³ãã¥ããã£ã§ã¯ãã¿ããªç¥ã£ãŠããããšãåæã«ãªã£ãŠããæè¡ãã«ã€ããŠå床åºç€ãåŠã¶ããšãããŠããããšãç®çãšããŠããŸãã
Discussion