Files
Alireza HassaniandCursor 11fd1cf454 Connect Meshkee catalog, customer login, and SEO sitemap config.
Wire products and articles to the public API, send guests to the customer portal, and publish sitemap-config for Meshkee nginx.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-03 09:31:15 +03:30

4.3 KiB

Sohan Salehnia Website Context

Project

  • Persian RTL storefront clone of sohansalehnia.com (سوهان صالح نیا).
  • Next.js 16 App Router, React 19, TypeScript, Tailwind 4, src/app.
  • Language: fa, direction: rtl.
  • Local images: public/images. Fonts: public/fonts.

Meshkee API

  • Docs: https://api.meshkee.com/docs/website
  • API base: https://api.meshkee.com/api/v1
  • Tenant domain: sohansalehnia.com (TENANT_DOMAIN in src/lib/meshkee.ts, src/lib/config.ts)
  • All public fetches go through src/lib/meshkee.ts. Authenticated calls go through src/app/api/* + src/lib/meshkee-server.ts.
  • Tenant id is 32 (Salehnia Sohan / salehnia-sohan). Enabled modules: products, blog, finance.

Auth / account

  • Guest login/user icon → https://customer.sohansalehnia.com
  • Logged-in header shows {name} عزیز with dropdown: پروفایل من, خروج, and مدیریت وبسایت if admin.
  • Profile: https://customer.sohansalehnia.com/profile
  • Admin dashboard: https://business.sohansalehnia.com via /api/auth/handoff
  • Session: src/lib/session.tsx + shared cookies in src/lib/shared-auth-cookie.ts
  • Favicon: GET /tenants/sohansalehnia.com/website/favicon. If faviconUrl is empty, fall back to /images/logo.png.

Routes

Path Source
/ static homepage clone
/aboutus static about
/contactus static contact (form still local)
/products GET /tenants/{domain}/products
/products/[id]/[slug] product by id + technical-info + comments + similar
/articles GET /tenants/{domain}/blogs
/articles/[id]/[slug] blog by id + comments

Product detail: lightbox gallery, hover zoom, tabs (توضیحات / اطلاعات فنی / دیدگاه‌ها). Comments require login; guests see a login box.

SEO + sitemap

  • Do not add public/sitemap.xml or public/robots.txt (nginx proxies both to Meshkee API).
  • Live sitemap is an index: /sitemap.xml → /sitemap-main.xml + /sitemap-products.xml.
  • Static pages: GET /meshkee/sitemap-config.json (generated at build from app routes).
  • Generator: scripts/generate-sitemap-config.mjs → src/lib/sitemap-config.generated.json
  • Run manually: npm run generate:sitemap-config
  • Excludes api, meshkee, admin, auth, login, checkout, cart, account
  • Blog / product details are not listed in sitemap-config (Meshkee XML covers CMS URLs)
  • After deploy: business dashboard → Website → Settings → Sync sitemap config (needed for static pages)

Canonical URL shapes

Meshkee defaults — omit templates unless customized. This site customizes blog to /articles:

  • Product: /products/{id}/{nameFaSlug} → GET /tenants/{domain}/products/by-id/{id}
  • Category: /products/category/{id}/{nameFaSlug} (not built; catalog empty)
  • Blog: /articles/{id}/{titleSlug} → GET /tenants/{domain}/blogs/by-id/{id} (templates.blog in sitemap-config)
  • Portfolio: not built
  • Slugify (src/lib/slugify.ts): Farsi letters kept, spaces → -, strip other punctuation. Do not use legacy DB slug in public URLs.

On-page SEO

  • Helper: src/lib/seo.ts (pageMetadata, unique absolute <title>, clipped meta description ~158 chars, canonical, OG)
  • Homepage title is unique (سوهان صالح نیا | تولید و عرضه سوهان سنتی قم) and does not rely on the Next.js default
  • Exactly one visible H1 per page (PageHeader wraps kicker + gold title; homepage H1 is the product-types row). Do not use sr-only H1.
  • H2/H3 for real sections (feature block, why-us, similar/related, comments)
  • Prefer CMS nameFa / title / summary / descriptionHtml for product and article metadata
  • Content images have meaningful alt (CMS title when available). Decorative pattern uses alt=""
  • src/app/not-found.tsx: unique title + one H1, noindex

Brand

Token Value
Primary #706C01
Gold #868215
Page #F9F9F9
Heading #4B4B4B
Muted #5E5E5E

Notes

  • Products and blogs may be empty until published in Meshkee.
  • Do not invent Meshkee endpoints. Product specs use .../products/by-id/{id}/technical-info (join form.fields[].id ↔ values[].fieldId).
  • Keep CONTEXT.md updated when routes, brand tokens, or data sources change.