<!-- Source: https://interview-questions.io.nexus/frontend-bookmarks -->

# Frontend Interview Task

Edge Saved – Article Bookmarking App

## Time Limit

1 hour

## Goal

Build a small server-side rendered web application using Cloudflare Workers and React Router (v7).

The app allows users to bookmark articles, with bookmark state rendered via SSR and persisted using signed cookies.

## Functional Requirements

### 1. Routes & Pages (SSR required)

#### GET / — Article List Page

- Display a list of articles (hard-coded data is fine, ~10 items).
- Each article shows:
  - Title
  - Short description
  - A Bookmark / Unbookmark button
- At the top of the page, show: “Bookmarked: X articles”

**SSR requirement**

On first load, bookmark status must be rendered on the server using data from cookies (not client-only state).

#### GET /saved — Bookmarked Articles Page

- Display only bookmarked articles.
- If there are no bookmarked articles:
  - Show an empty-state message
  - Provide a link back to /

### 2. Bookmark Toggle (Action)

POST /toggle (or equivalent action)

- Receives an articleId
- Reads current bookmarks from cookies
- Toggles bookmark state
- Writes updated state back via Set-Cookie
- Returns:
  - Minimum: a redirect back to the previous page
  - Optional (bonus): use useFetcher() for a no-reload toggle

### 3. Signed Cookie (Required)

Bookmark state must be protected against tampering.

- Store bookmark data in a cookie payload, e.g.:

  ```json
  { "ids": ["a1", "a3"], "iat": 1700000000 }
  ```

- Sign the payload using HMAC-SHA256
- Cookie format example:

  ```text
  base64(payload).base64(signature)
  ```

- Use an environment secret: `APP_SECRET`

**Important**

- Use Cloudflare Workers Web Crypto API (crypto.subtle)
- Do not use Node.js crypto
- If signature verification fails:
  - Treat the cookie as invalid (empty bookmarks or clear cookie)

### 4. Headers & SSR Behavior

- All loaders/actions must run on the server (Workers runtime)
- Responses that depend on user cookies must include: `Cache-Control: private, no-store`
- Bookmark cookie should include reasonable attributes:
  - HttpOnly
  - Secure
  - SameSite=Lax
  - Path=/

### 5. Error Handling

- Implement at least one Error Boundary or errorElement
- Example cases:
  - Cookie parsing/signature verification failure
  - Unexpected loader/action errors
- Error UI can be minimal but should be user-friendly

## Constraints

To keep the scope reasonable:

- ❌ No database (D1, KV, external DB not required)
- ❌ No authentication system
- ❌ No complex UI or styling
- ✅ Hard-coded article data is acceptable
- ✅ TypeScript is strongly recommended

## Deliverables

1. GitHub repository URL
2. Development process documentation
3. Deployment to Cloudflare Workers
4. A demonstration video recorded by yourself after development is completed
