A bilingual (HR/EN) Home Assistant resource hub built with Astro and managed through Decap CMS.
This README is intentionally focused on development workflow, tips, and troubleshooting.
- Astro 5 (content collections + static build)
- YAML content files (
src/content/**) - Decap CMS (
/admin) with local backend for local editing - Deploy target: Cloudflare Pages (static output)
npm install
npm run dev- Site:
http://localhost:4321 - CMS:
http://localhost:4321/admin
For local Decap editing (recommended), run this in a second terminal:
npm run decapnpm run dev- Start Astro dev servernpm run build- Production build intodist/npm run preview- Serve built output locallynpm run decap- Start local Decap proxy server
src/
pages/
index.astro # Main page, content rendering, interactive behavior
admin.astro # Decap CMS bootstrap page
layouts/
BaseLayout.astro # Meta tags, social cards, global layout shell
styles/
global.css # Theme and component styling
content/
config.ts # Zod schemas for all content collections
site/home.yml # Global copy, section labels, i18n defaults
integrations/*.yml # Integration cards
scripts/*.yml # Script/resource links
projects/*.yml # Project cards
public/
admin/config.yml # Decap CMS configuration
admin/preview.js # CMS live preview logic
All user-facing content is validated by src/content/config.ts.
- Keep localized fields complete (
hranden) to avoid fallback gaps in UI. - Use valid absolute URLs for all link fields (
docsUrl,repoUrl,url, social links). ordercontrols sorting. Lower numbers render first.accentColorin integrations must be hex (e.g.#60a5fa).
- Edit YAML directly in
src/content/**for fast dev iterations. - Use
/adminwhen non-technical editors need a safe UI. - Keep schema (
config.ts) and CMS fields (public/admin/config.yml) aligned when adding fields.
If you add/change a field:
- Update Zod schema in
src/content/config.ts - Update corresponding collection fields in
public/admin/config.yml - Update rendering in
src/pages/index.astro
If one of these is missed, content edits may fail validation or not render.
The page uses data-entry-id / data-entry-name attributes for preview updates.
Tip:
- Keep
nameunique inside each collection. - Avoid mass-renaming entries unless needed, because preview matching can become ambiguous.
Language toggle reads data-hr / data-en attributes in the DOM.
Tip:
- For rich text fragments (hero title), keep HTML generation centralized in one place.
- For normal text, avoid injecting HTML and keep
textContentupdates only.
Theme mode is persisted in cookies (light, dark, auto) and auto follows prefers-color-scheme.
Tip:
- When debugging visual bugs, clear cookies first to eliminate stale theme/lang state.
Avatar is loaded from a URL and falls back to a text avatar on load error.
Tip:
- Prefer stable image URLs (GitHub avatar is fine).
- Test broken URL behavior intentionally once after avatar logic changes.
All lists are sorted by order.
Tip:
- Leave gaps in numbering (
10, 20, 30) so future inserts do not require reshuffling.
Tip:
- Keep indentation consistent (2 spaces).
- Quote values that contain
:or special characters. - Use
ymlextension consistently, matching Decap config.
- Create
src/content/integrations/<slug>.yml - Add required fields (
order,name,icon,source,description,docsUrl,repoUrl,repoDisplay,repoChip,accentColor) - Reload dev server if schema-related errors appear
- Add field to
src/content/site/home.yml - Add schema in
src/content/config.ts - Render it in
src/pages/index.astro - Add field in
public/admin/config.ymlso CMS can edit it
Edit src/layouts/BaseLayout.astro:
meta description- Open Graph/Twitter values
- social image logic (
/social-image.png)
- Ensure
npm run decapis running locally. - Confirm
local_backend: trueexists inpublic/admin/config.yml. - Check browser console/network for
decap-serverproxy errors.
- Check schema errors from Astro content collection validation.
- Confirm YAML field names match schema exactly.
- Confirm URLs are valid where
z.string().url()is required.
- Ensure
public/admin/preview.jsis loaded. - Confirm entry
name/slug mapping still matches DOM selectors. - Refresh
/adminafter structural template changes.
- Build command:
npm run build - Output directory:
dist - This is a static Astro site, so standard Pages static deployment works.
If using Decap in production, make sure GitHub OAuth/auth is configured correctly for the github backend.
- Cloudflare Dashboard -> Workers & Pages -> Create -> Pages -> Connect to Git
- Select
BrunoAFK/HA-Resource-Hub - Build settings:
- Framework preset:
Astro(orNone) - Build command:
npm run build - Build output directory:
dist - Node.js version:
20.13.1(matches.nvmrc)
- Framework preset:
- Deploy
- Open your Pages project -> Custom domains
- Add domain/subdomain and complete DNS instructions
- Wait for SSL to become active
local_backend: true only helps on localhost. Live Decap login needs OAuth proxy.
- Create a GitHub OAuth App:
- Homepage URL: your live site URL
- Authorization callback URL:
<oauth-proxy-url>/callback
- Deploy Decap OAuth proxy (for example via Cloudflare Worker using Decap's official template)
- Set proxy env vars/secrets:
OAUTH_CLIENT_IDOAUTH_CLIENT_SECRET
- In
public/admin/config.yml, set:backend.base_urlto proxy URLbackend.auth_endpoint(usuallyauth)
- Redeploy Pages
- Open
/admin - Login with GitHub
- Edit one test entry and save
- Confirm commit appears in
main - Confirm site redeploys and content is visible live
- Keep
dist/out of commits unless explicitly required by your release flow. - Validate links quickly before publishing changes (especially docs/repo URLs).
- Keep commit scope narrow: schema + content + rendering in one coherent change set.
Add your preferred license (MIT/Apache-2.0/etc.) in a LICENSE file.