This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
"נמלה פיננסית" (Nemala Finansit) — a Hebrew (RTL), SEO-driven financial content and tools site for the Israeli market (blog guides on קופות גמל / חיסכון לכל ילד, plus interactive calculator tools). Built with Eleventy (11ty) as a static site generator; there is no client-side framework — pages are Nunjucks templates and vanilla JS.
The dynamic backend (auth, user profiles, admin impersonation, mailer, gemel-data API) lives in a separate repository, deployed at the URL in siteconfig.js (serverUrl, currently https://classify-tkep.onrender.com) and is not part of this codebase. This site is a static frontend that calls that API via window.SITE_SERVER_URL.
npm start # prebuild (fetch gemel data) + eleventy --serve, local dev server with live reload
npm run build # prebuild + eleventy, production build to _site/
node scripts/build/fetch-gemel-data.js # run the data prebuild step alone
There is no configured test suite (npm test is a placeholder) and no linter. There is no build step for JS/CSS — files under scripts/ and styles/ are passed straight through to _site/ unminified (see .eleventy.js addPassthroughCopy).
.eleventy.js). (the whole repo), output is _site. Includes live in _includes.styles/, scripts/, assets/, and any .css/.js files colocated inside pages/** are passthrough-copied verbatim (no bundling).site comes from siteconfig.js (site name, canonical URL, backend serverUrl); env.SITE_SERVER_URL comes from process.env.SITE_SERVER_URL (falls back to http://localhost:3000), loaded via dotenv from .env.sharesTag (tag-overlap check used by "next read" recommendations) and date (Luxon-based, accepts moment-style YYYY/DD tokens).scripts/build/fetch-gemel-data.js)Runs before every build/serve. Hits the backend API ({serverUrl}/api/blog/kids-savings-gemel-data and /api/blog/gemel-invest-data) and writes the JSON responses to assets/data/blog/kids-savings/ and assets/data/blog/gemel-invest/, which blog pages then read at build time to render comparison tables. Fails soft: on fetch error it logs a warning and exits 0 so the build proceeds using whatever data file already exists on disk — don't assume a build failure means this step is broken.
_posts collectionThere's no posts collection convention. Content lives directly under pages/ as .md files (or index.md for a directory-as-page), each with front matter (layout, title, description, date, tags, thumbnail, breadcrumbs, css, scripts, bodyClass). Directory layout mirrors the URL structure:
pages/blog/<topic>/ — grouped guides (e.g. kids-savings, gemel-invest), each topic has an index.md hub page plus individual article .md files.pages/tools/<tool-name>/ — one directory per interactive tool, colocating index.md with its own script.js/style.css/helper JS files (e.g. renderResults.js, tool-conversion.js, plan-editor.js). These per-tool assets are referenced from front matter (css:, scripts:) and passed through by Eleventy, not imported/bundled.pages/registered/ and pages/admin/ — pages gated by client-side Firebase auth state (see below), same colocated-assets pattern._includes/)base.njk is the HTML shell: meta tags, OG/Twitter cards, canonical URL, Firebase/GA/AdSense script tags, and global includes (nav.njk, impersonation-banner.njk, footer). Layouts extend it and override head/content blocks:
layout.njk — plain content pages (home, tool index, blog index).layouts/post.njk — blog articles; also injects BlogPosting JSON-LD structured data from front matter.layouts/tool.njk — interactive tools; adds a two-aside (rightAside/leftAside) layout shell for ad slots and a "Next Read" section.layouts/registered.njk — logged-in-only pages, same aside/next-read shell, no breadcrumbs.layouts/dialog.njk — modal/dialog layout._includes/next-read.njk auto-picks up to 3 related posts by shared front-matter tags (via the sharesTag filter) from collections.all, excluding generic tags (post, blog). _includes/breadcrumbs.njk renders from a breadcrumbs front-matter array, or falls back to Home + current title.
scripts/, no bundler)Every script is a plain <script defer> tag added either globally in base.njk or per-page via front-matter scripts:. Cross-script communication happens through globals attached to window (e.g. window.NemalaImpersonation, window.SITE_SERVER_URL, window.NemalaToolRoutes referenced from scripts/auth-redirect.js) — there are no ES modules or imports. When adding a script, add its <script> tag explicitly; nothing is auto-discovered.
scripts/firebase-init.js — initializes the Firebase app (compat SDK, loaded from CDN in base.njk) once, guarded by firebase.apps.length.scripts/impersonation.js — admin "view as user" flow: exposes window.NemalaImpersonation.{startImpersonation, endImpersonation, isImpersonating}, backed by {SITE_SERVER_URL}/api/admin/impersonate* endpoints, session state kept in sessionStorage, and toggles the banner in _includes/impersonation-banner.njk.scripts/auth-redirect.js — shared next/UTM param handling for the signup/login flow (buildSignupUrl, getAuthRedirectUrl); guards against open-redirect by requiring a leading single /.scripts/base.js, scripts/navbar.js, scripts/lazy-ads.js, scripts/read-next.js, scripts/GA.js — global chrome (login-state margin adjustment, nav, lazy AdSense loading, "next read" click tracking, analytics).localStorage.getItem("userData") for a cached user and also subscribe to firebase.auth().onAuthStateChanged(...) to reconcile (see scripts/base.js).${window.SITE_SERVER_URL}/api/... with a Firebase ID token as a Bearer auth header where auth is required (see scripts/impersonation.js, pages/registered/my-profile/script.js, scripts/signup.js, scripts/contact.js).Note: base.njk includes <script src="/scripts/tool-routes.js" defer>, but that file does not currently exist in this repo — check before assuming NemalaToolRoutes is defined.
styles/)Plain CSS, no preprocessor, no bundling — one stylesheet per layout/page area under styles/layouts/, styles/blog/, styles/components/, plus shared base.css/navbar.css/ads.css. Tool/blog pages typically add their own colocated style.css referenced via front-matter css:.
All content and templates are Hebrew, dir="rtl". File and directory names for blog articles are frequently in Hebrew (e.g. pages/blog/kids-savings/חיסכון-לכל-ילד.md) — this is intentional and mirrors the live URL structure, not a mistake to "fix".