project overview
tramhay is a personal digital garden directory. it collects sách (books), công cụ (tools), đồ vật (physical products), thương hiệu (brands), bài viết (articles), nghe (audio), xem (visual), and ý tưởng (ideas) — anything i find valuable, organized by topic rather than chronologically.
the name: "trăm" (hundred) + "hay" (good/interesting) = "a hundred good things."
content model
each entry is a markdown file in src/content/entries/. the frontmatter contains structured data; the body contains personal "growing notes" written over time.
frontmatter fields
| field | required | type | description | |||
|---|---|---|---|---|---|---|
| ------------- | ---------- | ---------- | ------------------------------------ | |||
| title | yes | string | lowercase entry name | |||
| url | yes | url | link to the thing | |||
| description | yes | string | one-line what-it-is | |||
| tags | yes | string[] | cross-cutting descriptors | |||
| topic | yes | string | primary garden bed | |||
| added | yes | date | date first planted | |||
| tended | no | date | last updated (defaults to added) | |||
| status | no | enum | seedling | growing | blooming | evergreen |
| via | no | string | who/what recommended this | |||
| image | no | string | optional preview image path | |||
| display | no | enum | image | text | default (card layout) |
taxonomy
topics are broad groupings — garden beds:
| topic | what goes in it |
|---|---|
| --------------- | ------------------------------------------ |
| sách | books worth reading |
| công cụ | software, apps, digital utilities |
| đồ vật | physical products, everyday items, gear |
| thương hiệu | brands, shops, makers worth following |
| bài viết | blog posts, essays, articles |
| nghe | podcasts, music, audio |
| xem | youtube channels, films, visual content |
| ý tưởng | concepts, frameworks, mental models |
tags are specific descriptors — plant labels: cross-cutting, free-form, auto-lowercased
status is growth stage:
- seedling: just added, not yet explored
- growing: actively using/evaluating
- blooming: highly recommended, well-understood
- evergreen: timeless, always relevant
content creation workflow
- create a new
.mdfile insrc/content/entries/(kebab-case filename) - fill in frontmatter using the template
- write personal notes in the body (markdown, informal voice)
- set
status: "seedling"andaddedto today - commit with
add [title] entryand push — cloudflare auto-deploys
tending an entry: update the body, bump tended, adjust status if opinion changed.
status upgrade path: seedling → growing → blooming → evergreen. move up when confidence increases; evergreen means 6+ months of proven value.
no database, no cms, no build step beyond npm run build.
routing
| route | purpose |
|---|---|
| ---------------------- | -------------------------------------- |
/ |
homepage, entries grouped by topic |
/entries/[slug] |
individual entry with growing notes |
/tags |
all tags index |
/tags/[tag] |
entries filtered by tag |
/topics/[topic] |
entries filtered by topic |
all routes are static, pre-rendered at build time via getStaticPaths().
data flow
getCollection('entries')loads all entries at build timesrc/lib/garden.tsprovides grouping/sorting helpers- each page filters/sorts as needed for its view
entry.render()renders the markdown body to html on entry detail pages
deployment
cloudflare pages, static output. no adapter needed. build command: npm run build (runs astro build) output directory: dist