# Akarya Website

Production-ready company profile website for PT Akarya Solusi Kreatif, built with Next.js App Router, TypeScript, Tailwind CSS, a headless REST API for content, bilingual content, and SEO foundations.

## Stack

- Next.js 16 App Router (static export)
- React 19
- TypeScript
- Tailwind CSS 4
- Content REST API (`/api/v1/...`), consumed at build time
- Zod contact form validation
- `next/font` and `next/image` ready

## Local Development

```bash
npm install
npm run dev
```

Open:

- English default: `http://localhost:3000`
- Bahasa Indonesia: `http://localhost:3000/id`

The content API must be reachable during `npm run dev` and `npm run build` — the
site is a static export and reads all content at build time.

## Environment

Copy `.env.example` to `.env.local` and adjust:

```bash
NEXT_PUBLIC_API_URL=http://127.0.0.1:8000
NEXT_PUBLIC_SITE_URL=https://www.akarya.id
NEXT_PUBLIC_CONTENT_REVALIDATE_SECONDS=10
CONTACT_DELIVERY_MODE=placeholder
```

`NEXT_PUBLIC_API_URL` is the origin of the content backend, without a trailing
slash. Endpoints are served under `${NEXT_PUBLIC_API_URL}/api/v1/...`.

## Content API

All content is fetched in `lib/content.ts` from these endpoints:

| Endpoint | Content |
| --- | --- |
| `/api/v1/site-settings` | Site settings singleton |
| `/api/v1/homepage` | Homepage singleton — hero slides, overview + metrics, showcase, products, room designer |
| `/api/v1/solutions` · `/solutions/{slug}` | Solutions list + detail |
| `/api/v1/products` · `/products/{slug}` | Products list + detail (`?featured=1`) |
| `/api/v1/industries` · `/industries/{slug}` | Industries list + detail (includes FAQ blocks) |
| `/api/v1/case-studies` · `/case-studies/{slug}` | Case studies (`?featured=1`, `?industry=`) |
| `/api/v1/partner-brands` | Partner brands list |
| `/api/v1/blog-posts` · `/blog-posts/{slug}` | Blog / insight posts |

Behavior:

- Only published records are returned; `{slug}` lookups 404 on miss.
- Translated fields are returned as `{ "en": …, "id": … }` objects (the shape the
  UI expects). The frontend does not pass `?locale=`.
- Newline-stored list fields are returned already split into arrays.
- Related content is exposed as slug arrays (`relatedSolutions`,
  `relatedCaseStudies`); case-study `partnerBrands` as brand-name arrays.
- Responses are wrapped in a `{ "data": ... }` envelope.
- Relative media `url` values are prefixed with `NEXT_PUBLIC_API_URL` at fetch time.

The `SiteSettings` object consumed by the app merges `/site-settings` with the
homepage fields from `/homepage` (`homepageHeroSlides`, `homepageOverview`,
`homepageShowcase`, `homepageProducts`, `roomDesignerPage`).

## Routes

- `/`
- `/id`
- `/about`
- `/id/about`
- `/solutions`
- `/solutions/[slug]`
- `/id/solutions/[slug]`
- `/industries`
- `/industries/[slug]`
- `/success-stories`
- `/success-stories/[slug]`
- `/insights`
- `/insights/[slug]`
- `/room-designer`
- `/talk-to-akarya`
- `/privacy-policy`

## SEO

Implemented:

- Metadata API per route and locale
- Canonical and hreflang alternates
- Open Graph and Twitter Card metadata
- `sitemap.xml`
- `robots.txt`
- Organization, LocalBusiness, WebSite, BreadcrumbList, BlogPosting, and CreativeWork JSON-LD
- Semantic headings and accessible form labels

## Contact Form

The contact form posts to `/api/contact` and validates:

- name
- company
- email
- phone
- projectType
- message

The API route currently returns a placeholder success response. Connect it to email, CRM, or database when production delivery is ready.

## Quality Checks

```bash
npm run lint
npm run typecheck
npm run build
```

## Deployment

The build produces a static export in `out/`. Set `NEXT_PUBLIC_SITE_URL` to the
production domain and `NEXT_PUBLIC_API_URL` to the production content API before
building so canonical URLs, sitemap, hreflang, and content are correct.

## Production Checklist

- Add real project photography and optimized OG image assets in the content backend.
- Confirm the content API is reachable from the build environment.
- Connect contact form to email, CRM, or database.
- Confirm production domain and DNS.
- Review final copy with Akarya internal team.
- Run Lighthouse on desktop and mobile after real assets are added.
