Build the RTL Next.js experience with live catalog, journal, customer interactions, and SEO-ready canonical routes. Co-authored-by: Cursor <cursoragent@cursor.com>
104 lines
6.8 KiB
Markdown
104 lines
6.8 KiB
Markdown
# Glassmond project context
|
|
|
|
## Goal
|
|
|
|
Persian RTL Next.js recreation of the public Glassmond website. Current scope is:
|
|
|
|
- Homepage (`/`)
|
|
- Products (`/products`) and canonical product details (`/products/{id}/{nameFaSlug}`)
|
|
- Product categories (`/products/category/{id}/{nameFaSlug}`)
|
|
- Blog (`/blog`) and canonical article details (`/blog/{id}/{titleSlug}`)
|
|
- About (`/about`)
|
|
- Contact (`/contact`)
|
|
- Features (`/features`)
|
|
|
|
The visual source of truth is `https://www.glassmond.com`. Public copy, logo, product imagery, banners and Iran Yekan font were downloaded from the source site. The footer's final black credit row follows the compact treatment used by `https://brb-store.com`.
|
|
|
|
## Stack
|
|
|
|
- Next.js App Router
|
|
- TypeScript
|
|
- Plain responsive CSS in `app/globals.css`
|
|
- Lucide React icons
|
|
- Local Iran Yekan font files
|
|
|
|
## Important architecture
|
|
|
|
- Shared layout: `app/layout.tsx`
|
|
- Navigation: `components/header.tsx`
|
|
- Footer: `components/footer.tsx`
|
|
- Global intersection-based reveal controller: `components/motion-observer.tsx`
|
|
- Responsive five-card product carousel: `components/product-carousel.tsx`
|
|
- Typed Meshkee API client and canonical URL helpers: `lib/meshkee.ts`
|
|
- Build-time static route discovery: `scripts/generate-sitemap-config.mjs`
|
|
- Generated Meshkee sitemap payload: `data/generated-sitemap-pages.ts`
|
|
- Product gallery/lightbox: `components/product-gallery.tsx`
|
|
- Auth-aware account UI: `components/auth-provider.tsx` and `components/user-menu.tsx`
|
|
- Shared authenticated comment UI: `components/entity-comments.tsx`
|
|
- Reusable headings, feature grid, video CTA and inner-page hero: `components/sections.tsx`
|
|
- Static feature and contact presentation data: `data/site.ts`
|
|
- Public source-site assets: `public/images` and `public/fonts`
|
|
|
|
Products and blogs now come from the Meshkee Website API. The homepage, listing pages, details, approved comments and contact form use the live `glassmond.com` tenant. Local files remain as visual fallbacks only.
|
|
|
|
The contact form validates in the browser and submits through `app/api/contact/route.ts` to Meshkee's public contact-submission endpoint.
|
|
|
|
## Meshkee backend
|
|
|
|
- API base: `https://api.meshkee.com/api/v1`
|
|
- Apex tenant domain: `glassmond.com`
|
|
- Resolved business ID: `22`
|
|
- Public content always uses `/tenants/glassmond.com/...`
|
|
- Customer portal: `https://customer.glassmond.com`
|
|
- Business/admin portal: `https://business.glassmond.com`
|
|
- The account provider recognizes Meshkee bearer tokens from the common browser token keys and validates them with `GET /auth/me`. Logged-in users see `{firstName} عزیز`, profile/logout actions, and the management link when their API role is administrative.
|
|
- Comment submission is UI-gated to authenticated users. Approved comments remain publicly readable.
|
|
- CMS HTML is sanitized server-side with `sanitize-html` before rendering.
|
|
- Remote CMS media is optimized through Next Image and restricted in `next.config.ts` to the tenant's ParsPack media path.
|
|
- Meshkee discovery manifests are exposed at `/meshkee/static-image-slots` and `/meshkee/sitemap-config.json`.
|
|
|
|
## SEO architecture
|
|
|
|
- `npm run build` executes `npm run seo:generate` first. The generator scans `app/**/page.*`, includes only public static pages, and excludes dynamic segments plus auth, cart, checkout, admin, API and Meshkee utility routes.
|
|
- Do not add `public/sitemap.xml`, `public/robots.txt`, `app/sitemap.ts` or `app/robots.ts`. Production nginx proxies the sitemap index, sitemap parts and robots file from the Meshkee API.
|
|
- Every public static route has a unique title, description, explicit canonical URL and Open Graph metadata.
|
|
- Product/blog search and category-filter query variants are `noindex,follow`; paginated lists have self-referencing canonicals and page-specific metadata.
|
|
- Product, product-category and blog detail pages derive metadata and canonical URLs from current CMS fields. The API ID resolves content; the Persian slug is SEO-only and stale slugs redirect.
|
|
- All crawlable pages render one H1. Section structure uses H2/H3, including a screen-reader H2 for compact feature sections.
|
|
- Content images and gallery thumbnails use descriptive Persian alt text or CMS titles.
|
|
- Sanitized CMS body images are allowed only with safe attributes, receive a meaningful title-based fallback alt, and load lazily.
|
|
|
|
## Design system
|
|
|
|
- Direction/language: RTL / Persian (`fa`)
|
|
- Strict monochrome palette: black accents on light surfaces and white accents on dark/image surfaces; no red
|
|
- Main dark: `#1b1b1b`
|
|
- Soft dark: `#3b3b3b`
|
|
- Warm surface: `#f6f1f0`
|
|
- Cream surface: `#fef8f4`
|
|
- Font: Iran Yekan
|
|
- English section labels use the source site's Montserrat Alternates Light font for a geometric Glassmond-like character. Labels include NEW PRODUCTS, OUR STORY, WHY GLASSMOND, JOURNAL, ABOUT GLASSMOND, OUR SERVICES and contact labels.
|
|
- About and contact inner-page heroes use matching English labels. The About page includes a monochrome experience/innovation/support statistics band.
|
|
- Square edges, editorial spacing, black/white surfaces and dark feature/footer sections
|
|
- Typography is intentionally light and compact. Header links use light weight; only the current route uses regular weight with a thin white underline. The header contains no red.
|
|
- Body copy uses light weight while section headings and key labels use bold weight to create hierarchy without color.
|
|
- Motion uses staggered hero/page-hero text entry, a header drop-in, one-time scroll reveals for sections/cards and a staggered product carousel transition. It is disabled when `prefers-reduced-motion` is enabled.
|
|
|
|
## Source contact data
|
|
|
|
- Mobile/WhatsApp: `0930 129 3902`
|
|
- Factory: Qom, Samen industrial town, Alley 23
|
|
- Instagram and WhatsApp URLs are stored in `data/site.ts`
|
|
|
|
## Notes for future work
|
|
|
|
- Canonical detail links use API IDs; the Persian slug is SEO-only and stale slugs redirect to the current canonical path.
|
|
- Canonical product-category pages resolve through `GET /categories/by-id/{id}` and list products by `categoryId`.
|
|
- Product list and blog list support server-rendered search, category filtering and pagination.
|
|
- Product details include a hover zoom, lightbox gallery, description/comments tabs and related products.
|
|
- If the customer portal changes its token handoff/storage convention, update only `components/auth-provider.tsx`.
|
|
- The API currently returns no sellable variants or prices for the imported products, so product details use contact/WhatsApp ordering rather than cart actions.
|
|
- The portfolio module currently has no published items. Add `/portfolios` and `/portfolios/{id}/{titleFaSlug}` before publishing portfolio content so future sitemap entries resolve.
|
|
- The Features page combines source-site feature claims with detailed anti-fog, lighting, touch-control and 12V/IP64 explanations.
|
|
- Update this file whenever architecture, routes, backend integration, assets, or project conventions materially change.
|