Add portfolio, blog, customer login, and Meshkee SEO.
Wire CMS routes and account UI, match the original header icons, and publish sitemap-config with unique page metadata. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
co-authored by
Cursor
parent
d2a82849ef
commit
6cd85e7e59
+31
-9
@@ -7,8 +7,8 @@
|
||||
- Apex domain: `khiyalstudio.com`.
|
||||
- Language: `en`, direction: `ltr`.
|
||||
- Local images live in `public/images`; local fonts live in `public/fonts` (Antonio + Plus Jakarta Sans, matching the source site).
|
||||
- Public routes in this clone: `/`, `/about-us`, `/contact-us`.
|
||||
- Portfolio and blog listing/detail pages are **not** implemented yet; homepage cards use current site data as local placeholders until Meshkee portfolio/blog endpoints are wired.
|
||||
- Public routes: `/`, `/about-us`, `/contact-us`, `/portfolios`, `/portfolios/{id}/{slug}`, `/blog`, `/blog/{id}/{slug}`.
|
||||
- Homepage project/news cards still use local placeholders when Meshkee lists are empty.
|
||||
|
||||
## Source clone
|
||||
|
||||
@@ -22,11 +22,29 @@
|
||||
- Canonical docs: `https://api.meshkee.com/docs/website`
|
||||
- API base: `https://api.meshkee.com/api/v1`
|
||||
- Tenant domain: `khiyalstudio.com` (`SITE_DOMAIN` in `src/lib/site.ts`)
|
||||
- All public fetches go through `src/lib/meshkee.ts`. Do not call the API from components.
|
||||
- Enabled modules currently include `portfolio` and `blog`. This site does **not** use workshops.
|
||||
- All public GET fetches go through `src/lib/meshkee.ts`.
|
||||
- Empty or failed static-image slots keep local placeholders.
|
||||
- Do not invent dashboard/CMS/upload endpoints.
|
||||
- Do not add `public/sitemap.xml`, `public/robots.txt`, `app/sitemap.ts`, or `app/robots.ts`; nginx proxies these URLs to Meshkee.
|
||||
|
||||
## Customer account
|
||||
|
||||
- Login / user icon goes to `https://customer.khiyalstudio.com`.
|
||||
- Logged-in header shows `{firstName} عزیز` with dropdown: `پروفایل من`, `خروج`, and `مدیریت وبسایت` when the user is an admin (`https://business.khiyalstudio.com`).
|
||||
- Auth check: `GET /auth/me` with localStorage token (`accessToken` / `meshkee_access_token`) or credentials cookie.
|
||||
|
||||
## Content routes
|
||||
|
||||
| Kind | List | Detail | API |
|
||||
|---|---|---|---|
|
||||
| Portfolio | `/portfolios` | `/portfolios/{id}/{slug}` | `GET /tenants/{domain}/portfolios`, `.../portfolios/by-id/{id}` |
|
||||
| Blog | `/blog` | `/blog/{id}/{slug}` | `GET /tenants/{domain}/blogs`, `.../blogs/by-id/{id}` |
|
||||
|
||||
- Portfolio/blog details use Meshkee canonical `{id}/{slug}` URLs and redirect if the slug is stale.
|
||||
- Portfolio details: lightbox gallery, hover zoom, similar-projects row.
|
||||
- Detail galleries prefer `titleImageUrl` plus `gallery` URLs.
|
||||
|
||||
## Homepage static-image slots
|
||||
|
||||
Dashboard import catalog: `GET /meshkee/static-image-slots`.
|
||||
@@ -48,11 +66,15 @@ If a rendered image size or crop ratio changes, update the catalog in `src/app/m
|
||||
|
||||
## Sitemap and SEO
|
||||
|
||||
- `GET /meshkee/sitemap-config.json` is generated by scanning public static `src/app/**/page.*` routes.
|
||||
- Auth, admin, and Meshkee integration routes are excluded.
|
||||
- Do **not** add `public/sitemap.xml`, `public/robots.txt`, `app/sitemap.ts`, or `app/robots.ts`. Nginx proxies `/sitemap.xml` and `/robots.txt` to Meshkee.
|
||||
- Live sitemap index: `/sitemap.xml` → `/sitemap-main.xml` plus module sitemaps (`/sitemap-portfolios.xml`, `/sitemap-blogs.xml`).
|
||||
- `GET /meshkee/sitemap-config.json` is generated at build time by scanning public static `src/app/**/page.*` routes (`/`, `/about-us`, `/contact-us`, `/portfolios`, `/blog`). CORS `*` is set so the business dashboard can sync it (Website → Settings → Sync sitemap config).
|
||||
- Dynamic `{id}/{slug}` pages are omitted from that static list; Meshkee fills them from CMS. URL templates are omitted because this site uses Meshkee defaults (`/blog/{id}/{titleSlug}`, `/portfolios/{id}/{titleFaSlug}`).
|
||||
- Public slugs are built with `slugify()` (letters/numbers kept, spaces → `-`, punctuation stripped). Do **not** use the legacy DB `slug` field in public URLs. Portfolio slugs prefer `titleFa`; blog slugs prefer `title`.
|
||||
- Auth, admin, checkout, cart, and Meshkee integration routes are excluded.
|
||||
- Sitemap base URL uses `NEXT_PUBLIC_SITE_URL`, then `SITE_URL`, with `https://khiyalstudio.com` as the fallback.
|
||||
- Future portfolio/blog details must use Meshkee canonical `{id}/{slug}` URLs when those routes are added.
|
||||
- Every crawlable page must have unique metadata, exactly one H1, structured headings, and meaningful image alt text.
|
||||
- Every crawlable page has unique title + meta description (CMS fields on details), exactly one H1, H2/H3 for real sections, Open Graph, and meaningful image alt text (CMS `titleEn` / `title` / `titleFa` when available). 404 is `noindex`.
|
||||
- Shared helper: `src/lib/seo.ts` (`pageMetadata`).
|
||||
|
||||
## Contact
|
||||
|
||||
@@ -66,5 +88,5 @@ If a rendered image size or crop ratio changes, update the catalog in `src/app/m
|
||||
|
||||
- Run `npm run lint` and `npm run build`.
|
||||
- Verify `/meshkee/static-image-slots` returns the slot catalog.
|
||||
- Verify `/meshkee/sitemap-config.json` lists `/`, `/about-us`, and `/contact-us`.
|
||||
- Check homepage, about, and contact on desktop and mobile; hamburger menu, hero slider, and footer Meshkee credit should match the source palette.
|
||||
- Verify `/meshkee/sitemap-config.json` lists `/`, `/about-us`, `/contact-us`, `/portfolios`, `/blog`.
|
||||
- Check homepage, about, contact, and empty states for portfolios/blog. Header user icon should open the customer portal when logged out.
|
||||
|
||||
Reference in New Issue
Block a user