SEO admin panel
The directory for centrally managing the SEO / KW / topic-cluster strategy of niki-nakamura.github.io/til/.
It is excluded from the Jekyll build via _config.yml, so it does not appear on the public site.
Structure
seo/
├── README.md this file
├── KEYWORDS.md KW management (target / current rank / SV / status)
├── CLUSTERS.md topic-cluster strategy (the pillar ↔ cluster relationship map)
├── METRICS.md time-series metrics fetched from GSC / GA
├── config.json settings such as site URL / property ID / GA property (gitignored)
├── config.example.json settings template
├── package.json Node dependency (googleapis)
├── scripts/
│ ├── fetch-gsc.mjs GSC API → data/gsc-*.json
│ ├── fetch-ga.mjs GA4 Data API → data/ga-*.json
│ ├── update-rankings.mjs writes KEYWORDS.md back from data
│ └── weekly-report.mjs updates METRICS.md weekly
├── data/ API fetch results (gitignored)
└── credentials/ service-account.json etc. (gitignored)
Initial setup
1. Install dependencies
cd seo
npm install
2. Preparation on the Google Cloud side
- Create a GCP project (an existing HT project is fine)
- Enable the Search Console API and the Google Analytics Data API
- Create a service account → save the JSON key to
seo/credentials/service-account.json - GSC: settings for the target property at
search.google.com/search-console→ Users and permissions → add the service account's email as "Restricted" - GA4: Admin → Property Access Management → add the service account's email as "Viewer"
3. Create config
cp config.example.json config.json
Edit config.json and fill in siteUrl / gscProperty / gaPropertyId.
4. Check it works
node scripts/fetch-gsc.mjs
node scripts/fetch-ga.mjs
It is OK if JSON lands in data/.
Operating workflow
Daily (minimum)
Nothing to do. Summarise weekly.
Weekly (Niki manual or schedule skill)
node scripts/fetch-gsc.mjs # last 7 days of query / impression / click / position
node scripts/fetch-ga.mjs # last 7 days of sessions / users / engagement
node scripts/update-rankings.mjs # update the current-rank column in KEYWORDS.md
node scripts/weekly-report.mjs # add a row to METRICS.md
Monthly (strategy review)
- Review CLUSTERS.md: update pillar articles, add/remove clusters
- Re-evaluate the status in KEYWORDS.md: for KWs that remain "target" but whose ranking does not move, suspect the cluster strategy
The basics of the topic-cluster strategy
A structure in which a single pillar (a broad theme, a deep article) sits at the centre, with multiple clusters (concrete topics) connected by internal links.
- pillar: per TIL category (cognition / thinking / git / design / claude)
- cluster: an individual TIL entry
- internal links: pillar ↔ cluster is bidirectional; cluster ↔ cluster only when there is relevance
A KW with broad search intent (e.g. "metacognition") goes to the pillar; a narrowed KW (e.g. "how to use metacognition in learning") goes to a cluster.
Automatic referencing from CLAUDE.md
When handling this directory in Claude Code, enforcing in seo/CLAUDE.md or the repo-root CLAUDE.md that
> before writing a new TIL, check the not-started KWs in seo/KEYWORDS.md and the cluster plan in seo/CLUSTERS.md
will tie the choice of writing topic to the strategy.