# 7. Known Issues & Maintenance

A candid list of quirks, tech debt, and upkeep tasks discovered while documenting the codebase. None of these break the live site today, but knowing about them will save you confusion.

## Known quirks & tech debt

### Content is duplicated across files
The biggest maintenance hazard. The same content lives in multiple places that must be kept in sync:

- **News** appears in up to 4 spots: `articles` (`app/news/[slug]/page.tsx`), `newsArticles` + `newsItems` (`app/news/page.tsx`), and 3 hardcoded cards in `components/Landing.tsx`.
- **Contact info** (phone/email) is in both `app/contact-us/page.tsx` and `components/Landing.tsx`.
- **Navigation links** are in `components/Header.tsx` (`navLinks`) and again, hardcoded, in `components/Footer.tsx`.
- **Officer names** are in `app/about/page.tsx` (`officers`) and again as text in the `dcph-officers-trustees` article.

Every [editing recipe](05-content-editing-recipes.md) calls out the duplicate locations. A future improvement would be to extract shared content into a single `data/` module imported everywhere.

### Broken favicon metadata reference
`app/layout.tsx` declares `icons: { icon: "/favicon.png" }`, but **`public/favicon.png` does not exist**. This is harmless because Next.js auto-serves `app/favicon.ico` and `app/icon.png` (the App Router file convention), which is what the browser actually uses. **Fix options:** remove the `icons` line from `layout.tsx`, or add a real `public/favicon.png`.

### Dead Leaflet marker-icon references
`app/data-centers/FacilityMap.tsx` points Leaflet's default icon at `/images/marker-icon.png`, `/images/marker-icon-2x.png`, and `/images/marker-shadow.png` — **none of which exist** in `public/images/`. This is harmless because the map draws **custom `divIcon` markers** (`createCustomIcon`), so the default PNGs are never needed. The `useEffect` that sets them is effectively dead code. Safe to leave or remove.

### Unused dependency: `swiper`
`swiper` (`^12.1.3`) is in `package.json` but imported nowhere — the only carousel actually used is `embla-carousel-react` (on the News page). You can `npm uninstall swiper` to slim the install. (Verify with a quick search before removing.)

### Unused files
- `components/News.tsx` — a news-card component imported nowhere. Inert.
- `assets/purpose.png`, `assets/mission.png`, `assets/vision.png`, `assets/stt_bg.png` — not imported anywhere (the About cards use `react-icons` instead). Plus the default Next.js template SVGs in `public/` (`file.svg`, `globe.svg`, `next.svg`, `vercel.svg`, `window.svg`) are mostly unused.

These are safe to delete if you want to tidy up, but leaving them costs nothing.

### Confusing import alias
`components/Officers.tsx` default-exports a component called `OfficersSection`, but `app/about/page.tsx` imports it as `OfficerCard`. Same component, misleading local name. Cosmetic.

### `any` cast in the map
`FacilityMap.tsx` uses `(L.Icon.Default.prototype as any)._getIconUrl` to work around a Leaflet typing quirk. Standard workaround, just noting it since the project is otherwise strictly typed.

### Bleeding-edge dependency versions
The project runs **Next.js 16** and **React 19.2.3** — very recent majors. React/ReactDOM are pinned to an exact version (`19.2.3`), while Next is a caret range (`^16.2.1`). Expect occasional rough edges with third-party libraries that haven't caught up, and read upgrade notes carefully before bumping majors.

### No automated tests, no Prettier
There are no unit/integration tests. The old README claimed "ESLint, Prettier" but only ESLint is configured (no Prettier setup). `npm run build` (type-check + lint) is currently your main safety net — run it before every deploy.

## Pre-deploy checklist

Before pushing a change that goes live:

- [ ] The change looks right in `npm run dev` at desktop **and** mobile widths.
- [ ] `npm run build` completes with no errors.
- [ ] If you touched **news**, the slug matches everywhere and all links work (home, `/news`, the article itself).
- [ ] If you touched a **facility**, the name matches between `facilities` and `facilityCoordinates`, and the pin shows on the map.
- [ ] If you touched **contact info or nav links**, you updated *both* duplicated locations.
- [ ] New images are in the right folder (`assets/` for imported, `public/` for URL-referenced) and load correctly.
- [ ] Committed with a clear message; no stray `node_modules`/`.next` in the commit.

## Routine maintenance

### Keeping dependencies healthy
- Check for outdated packages: `npm outdated`.
- Apply non-breaking updates: `npm update`.
- For **major** version bumps (especially Next.js and React), do them one at a time, read the migration guide, and run `npm run build` + click through every page before deploying.
- Address security advisories: `npm audit` (use judgment with `npm audit fix --force`, which can introduce breaking changes).

### After any dependency change
Commit the updated `package-lock.json` alongside `package.json` — it pins exact versions so everyone (and the deploy) installs the same thing.

## Suggested future improvements

Not required, but they'd make the site easier to maintain:

1. **Centralize content** into a `data/` folder (one source of truth for news, officers, facilities, contact info) to kill the duplication described above.
2. **Centralize the color palette** as named tokens in the `@theme` block of `globals.css`, then replace the scattered `[#hex]` arbitrary values.
3. **Remove dead code/assets** (`swiper`, `components/News.tsx`, unused images, the broken favicon and Leaflet references).
4. **Consider a lightweight CMS or markdown-based content** if non-developers will need to publish news without editing code.
5. **Add a basic CI check** (run `npm run build` on every pull request) so broken changes are caught before merge.

## Glossary

| Term | Meaning |
| ---- | ------- |
| **App Router** | Next.js's routing system based on the `app/` folder. Folders = URLs. |
| **Server Component** | A component rendered on the server; the default. Can't use browser hooks/events. |
| **Client Component** | A component that runs in the browser. Declared with `"use client";` at the top. Required for state, effects, and event handlers. |
| **Route / page** | A URL on the site, defined by a `page.tsx` inside an `app/` subfolder. |
| **Dynamic route** | A route with a `[bracketed]` folder whose value is a variable (e.g., `news/[slug]`). |
| **Slug** | The URL-friendly identifier for a piece of content (e.g., `dcph-mou-signing`). |
| **Hydration** | The process where React attaches interactivity in the browser to server-rendered HTML. |
| **JSX/TSX** | The HTML-like syntax inside React components. `.tsx` = TypeScript + JSX. |
| **Tailwind utility class** | A single-purpose CSS class like `mb-4` (margin-bottom) or `text-[#333]`. |
| **Arbitrary value** | Tailwind's `[...]` syntax for one-off CSS values, e.g., `bg-[#FF3B30]`. |
| **`assets/`** | Images imported in code and optimized by Next.js `<Image>`. |
| **`public/`** | Static files served directly at root URLs (referenced by string). |
| **`<Image>`** | Next.js's optimized image component (vs. a plain `<img>`). |
| **`generateMetadata`** | A Next.js function that builds per-page SEO tags (title, Open Graph, etc.). |
| **Leaflet / react-leaflet** | The open-source mapping library powering the facility map. |
| **Embla** | The carousel library used for featured news. |
| **Hot reload** | The dev server auto-refreshing the browser when you save a file. |

---

← Back to the [documentation index](../README.md#-documentation)
