VARNI STOREFRONTS · QUALITY AUDIT · 2026-07-12
Live site: https://website-26.varnijewels.com · Design reference: myntra.com
Audited across three dimensions: launch readiness (functionality, SEO, performance, security, accessibility, analytics, brand), mobile QA (real device emulation, touch), and desktop QA (1920/1440/1366, hover + keyboard). Report-only — no purchase was completed.
Launch-readiness scoring. Infra-only items are marked MANUAL and left unscored.
| Category | Score | Verdict | Defects |
|---|---|---|---|
| Functionality (guest journey) | 40 | fail | 5 |
| Performance (Lighthouse + CWV) | 62 | warn | 3 |
| SEO (technical) | 35 | fail | 6 |
| Security (headers + surface) | 45 | fail | 4 |
| Frontend & Accessibility | 80 | warn | 4 |
| Analytics & Tracking | 0 | fail | 1 |
| Brand Consistency & Originality | 45 | fail | 5 |
| Marketing Readiness | 45 | warn | 3 |
| Backend / Infra (MANUAL) | — | manual | 2 |
| Monitoring & Maintenance (MANUAL) | — | manual | 1 |
Lighthouse CLI, mobile emulation defaults.
| Page | url | performance | accessibility | bestPractices | seo | LCP_s | CLS | TBT_ms | FCP_s | SI_s |
|---|---|---|---|---|---|---|---|---|---|---|
| home | https://website-26.varnijewels.com/ | 72 | 92 | 96 | 92 | 4.2 | 0.001 | 0 | 4.2 | 6.2 |
| pdp | https://website-26.varnijewels.com/products/033-carat-14k-rose-gold-igi-certified-lab-grown-princess-cut-diamond-solitaire-stud-earrings-for-women-pushback-closure-e-f-color-vs1-vs2-clarity | 64 | 89 | 96 | 100 | 9.5 | 0.001 | 20 | 3.7 | 4.8 |
34 findings across functionality, SEO, security, performance, accessibility, analytics and brand consistency.
Clicking any of the 5 main header nav links (matching CLAUDE.md's bare-slug /<term> convention) lands on a 200-OK page with 'NO PRODUCTS FOUND' / '0 Products', while /products shows 403 products exist in the catalog. Verified for /rings, /earrings, /necklaces, /bridal, /gifts via Playwright render + curl (all HTTP 200, not 404s) -- so this is a category/search-index tagging bug, not a routing bug: products are not tagged with the category slugs the nav/Meilisearch filter expects.
Fix: Fix product->category slug mapping in the Meilisearch index (categories field) so /rings, /earrings, /necklaces, /bridal, /gifts resolve the same 403-product catalog by category. This breaks the entire primary browsing path for every guest — launch blocker.
robots.txt correctly references https://website-26.varnijewels.com/sitemaps/website-26.varnijewels.com-sitemaps/sitemap_index.xml, but requesting /sitemap.xml returns {"message":"Sitemap not found, you can generate sitemap through the admin dashboard."} — no discoverable sitemap for crawlers.
Fix: Generate/publish the sitemap via the admin dashboard (per the error's own instruction) before launch; verify the robots.txt-referenced sitemap_index.xml URL actually resolves.
PDP <title> = '...(E-F Color, VS1-VS2 Clarity) | JewelWeSell'. og:title/og:description/twitter:description repeat 'JewelWeSell(s)'. The visible Product Description paragraph on the live page reads '...Presented in a JewelWeSell signature gift box...' — 12 occurrences of 'JewelWeSell' found in one PDP's raw HTML (title, 2x meta description, og:title, og:description, twitter:description, 2x rendered body text). Separately, og:site_name = 'Boris&Twins' (a second leaked reference brand), and JSON-LD Product schema sets "brand.name":"BorisAndTwins" / "manufacturer":"BorisAndTwins" on every listed product.
Fix: Sanitize the product feed/import pipeline: strip source-brand name/copy ('JewelWeSell', 'BorisAndTwins') from title templates, meta description templates, OG/Twitter templates, JSON-LD brand/manufacturer fields, and the raw product description body copy across all 403 products before launch. This is a copyright/plagiarism and brand-consistency risk per CLAUDE.md, and it's crawlable/shareable (search snippets, social previews, schema) even though the on-page header/footer/sidenav chrome is correctly branded WEBSITE-26.
og:site_name='Boris&Twins', JSON-LD Organization/WebSite name='Boris&Twins', Product JSON-LD brand.name/manufacturer='BorisAndTwins', page <title> suffix '| JewelWeSell' on every product, and 'JewelWeSell' phrasing baked into the visible product description copy itself ('Presented in a JewelWeSell signature gift box').
Fix: Same fix as SEO category: strip both leaked reference brands ('Boris&Twins'/'BorisAndTwins' and 'JewelWeSell') from schema, meta, and product copy across the catalog. This is the single biggest brand-consistency defect on the site — it undermines the entire rebrand even though the header/nav/footer are clean.
Clicked Carat Weight / Metal Color chips on PDP. Selected chip = 2px primary/pink border + bold dark text on white background; unselected chips = thin gray border + regular-weight dark text, same white background. Selected state is unmistakable and text is readable in every state.
Fix: None needed — meets the mandatory bar.
Lighthouse mobile-simulated PDP run: Performance score 64, LCP 9.5s (poor, threshold is <2.5s good / <4s needs-improvement). FCP 3.7s, Speed Index 4.8s, TBT 20ms, CLS 0.001 (excellent).
Fix: Investigate PDP hero image loading (preload the LCP image, serve responsive/next-gen formats, reduce render-blocking JS) — 9.5s LCP will fail Core Web Vitals in Search Console.
Home page Organization/JewelryStore schema contains a real-looking phone '(973) 399-9115', email '[email protected]', and street address '1060 Springfield Ave, Irvington Township, NJ 07111' — none of which belong to website-26/Varni. The logo URL filename is also 'boris-twins-zvmp0oimchiz.jpg'.
Fix: Replace contactPoint/address/logo in the Organization schema with the actual Website-26/Varni business details (or clearly-placeholder ones), not the reference site's real contact data.
curl -I on the homepage shows only Cloudflare/NEL/cache/cookie headers — none of the standard security headers are present.
Fix: Add standard security headers at the SvelteKit/edge layer (or Cloudflare Transform Rules): HSTS, X-Frame-Options or frame-ancestors CSP, X-Content-Type-Options: nosniff, Referrer-Policy, Permissions-Policy. Likely a fleet-wide gap (shared backend/theme), worth fixing once and rolling out.
Searched raw HTML of both home and PDP for gtag, dataLayer, googletagmanager.com, GTM-*, G-*, Facebook pixel (fbq/facebook.net/tr) — none found. No conversion tracking, no Enhanced Ecommerce events, no consent/cookie-banner script observed either.
Fix: Install GA4 (or GTM container) with Enhanced Ecommerce events (view_item, add_to_cart, begin_checkout, purchase, search) before launch — currently there is zero visibility into funnel drop-off or ad conversion.
Duplicate cross-reference — [email protected], +91 00000 00000, and bare social homepage links block a credible marketing launch.
Fix: Same fixes as above.
No way to measure marketing campaign performance, UTM attribution, or conversion goals without GA4/GTM.
Fix: Same fix as above.
Lighthouse home run: Performance 72, LCP 4.2s (needs improvement), FCP 4.2s, Speed Index 6.2s, TBT 0ms, CLS 0.001 (excellent).
Fix: Preload hero/LCP asset, reduce server response time (root doc took 870ms per Lighthouse), trim unused CSS (~26KiB estimated savings).
"@id":"https://https://website-26.varnijewels.com/#organization" and "url":"https://https://website-26.varnijewels.com" — invalid URLs in structured data.
Fix: Fix the URL-building logic that's prefixing an already-absolute URL with an extra 'https://'.
No GA4/GTM/gtag/dataLayer/Facebook pixel script tags found in home or PDP HTML.
Fix: See Analytics & Tracking category.
Set-Cookie header shows only Max-Age and Path; no Secure, HttpOnly, or SameSite flags.
Fix: Add Secure; HttpOnly (if not read client-side); SameSite=Lax/Strict to this cookie.
Category-tile meta text ('By Style · By Metal · By Stone') has contrast ratio 2.94 (needs 4.5:1) — foreground #94969f on white #ffffff, 12px normal weight.
Fix: Darken the category-tile meta text color to reach at least 4.5:1 contrast against white.
'WEBSITE-26' reads as a technical identifier rather than a jewelry brand name (compare sibling stores' named brands). Consistent everywhere, but not a finished brand identity.
Fix: Confirm with the business owner whether 'Website-26' is the final brand name for launch, or whether a real name/logo still needs to be assigned before go-live.
Footer email is [email protected] (the .example TLD is reserved/non-resolvable — this can never be a real inbox), phone is +91 00000 00000.
Fix: Replace with a real, monitored support email and phone number before launch.
CLS ~0.001 and TBT 0-20ms on both home and PDP — no layout shift or main-thread blocking issues.
Fix: None — keep as-is.
Footer contact links (e.g. support email link, 188.9x23.1px) are under the 24x24px minimum and lack spacing from neighbors.
Fix: Increase footer link row height/padding to reach 24px minimum target size.
Footer Instagram/Facebook/YouTube icons link to https://instagram.com, https://facebook.com, https://youtube.com — generic homepages rather than @website-26 (or brand) profile pages.
Fix: Point social icons to the store's actual social profiles, or remove the icons until real profiles exist.
Console shows 422 on /api/wishlists/me for guests. Per prior fix-list, this is expected behavior for unauthenticated users, not a bug.
Fix: No action — expected.
Add-to-cart, cart quantity/subtotal display, and Proceed to Shipping -> /checkout/address (contact details form) all functioned correctly for the tested PDP.
Fix: None — continues to work; payment step not attempted per instructions (no real purchase).
Curl-checked all 25 header nav links and all footer links; every internal path returned HTTP 200 (only /my/wishlist returns 307, expected redirect for guests).
Fix: None.
PDP canonical matches its own URL. curl confirms robots.txt returns 200 with sensible disallow rules (Lighthouse's 'robots.txt is not valid' finding could not download it in-run — likely a transient headless-fetch timeout, not a real defect, since curl retrieves it fine).
Fix: Re-verify robots.txt fetch in a follow-up Lighthouse run to rule out a one-off network hiccup; not treated as a confirmed defect here.
http:// requests 301-redirect to https://; TLS served via Cloudflare (HTTP/2, valid cert implied by successful curl over https).
Fix: None.
Not externally verifiable from a guest browsing session without attempting exploit/attack traffic, which is out of scope.
Fix: Ops team to confirm via backend/infra review (shared api.varnijewels.com backend, likely identical across the fleet).
Accessibility 92/100 (home), 89/100 (PDP); Best Practices 96/100 on both.
Fix: Fix the two flagged issues above to push toward 95+.
Mobile home, mobile sidenav, PLP, PDP, cart and checkout all rendered without visible overflow in captured screenshots.
Fix: None.
Header, mobile hamburger/sidenav, and footer all show the same 'WEBSITE-26' brandName. No 'Boris & Twins'-style leak was found in the on-screen sidenav (confirmed false on the specific regex check).
Fix: None for visible chrome.
Homepage/PDP/footer show 'Free insured shipping', '14-day returns', 'Certified diamonds (IGI/hallmarked)', '100% secure payments' trust rows.
Fix: None — good baseline trust signaling once contact/brand issues above are fixed.
The 0-products-per-category bug (Functionality category) is very likely a Meilisearch index/category-tagging issue on the backend (shared api.varnijewels.com) rather than a frontend routing bug, since all 5 category pages return HTTP 200 with an empty result set while /products lists 403 items.
Fix: Ops/backend team to check Meilisearch product documents' `categories` field values against the storefront's category slugs (rings/earrings/necklaces/bridal/gifts) for store_01KG2S7TF4HFHJQM0S3RYK73RM.
Not observable from the outside.
Fix: Ops team to verify via infra dashboards / Dokploy / server monitoring.
No monitoring dashboards observable from a guest browser session.
Fix: Confirm with ops which of these are configured fleet-wide (Dokploy, Cloudflare analytics, etc.) vs. still recommended.
Real mobile emulation (iPhone 13 (390x844, DPR3, touch, Mobile Safari UA) - Playwright headless Chromium, device descriptor devices['iPhone 13'], Pixel 7 (412x915, DPR2.625, touch, Chrome Mobile UA) - Playwright headless Chromium, device descriptor devices['Pixel 7'], Landscape spot-check on Home and Checkout (both profiles, rotated dimensions)), touch interaction, thumb-driven journey.
The bare `[slug]` category route - which is the canonical link target for every header nav link, every megamenu flyout link, and every homepage category tile - shows an empty 'NO PRODUCTS FOUND / Clear all filters' state on both mobile profiles. Confirmed reproducible on /rings, /earrings, /necklaces, /engagement-rings, /bridal, and /gifts. A network trace during navigation to /rings shows only /api/menu, /api/categories/all, /api/wishlists/me, /api/ms-autocomplete/products?search=, and /api/categories/megamenu firing - there is no Meilisearch/product-search API call for the category at all, so the category-to-product query never executes. By contrast, the full catalogue route /products DOES render the same products correctly (2-column grid, 20 products, working filter/sort), and the same rings/earrings/necklaces products are visible in the homepage category rails. This is a functional regression in the slug-to-category resolution, not a mobile-only styling bug, but it directly blocks the required PLP step of the mobile shopping journey since every nav entry point routes through it.
Fix: Fix the bare-slug PLP route's category query (server load function) so it actually issues the Meilisewrch products search with categories:<slug> and returns the same results /products shows. This is the single highest-priority defect in this audit: it silently breaks essentially all category browsing/navigation on the storefront, on both mobile and (very likely) desktop.
document.querySelectorAll('button[aria-label="Toggle Cart"]') returns 2 elements on the homepage/every page. The first wraps a magnifying-glass (lucide-search) SVG and is the search trigger; the second wraps a shopping-bag (lucide-shopping-bag) SVG and is the real cart trigger. A screen-reader/assistive-tech user tapping the search icon would hear 'Toggle Cart', which is actively misleading, and any automated test or accessibility tooling targeting 'Toggle Cart' will hit the wrong control.
Fix: Give the search trigger its own accurate label, e.g. aria-label="Open search" / "Toggle Search", distinct from the cart button's label.
button[aria-label="Decrease quantity"] and button[aria-label="Increase quantity"] on /checkout/cart both measure 28x28px on both iPhone 13 and Pixel 7 profiles. This is a primary, frequently-used cart interaction and is noticeably harder to hit precisely with a thumb than the surrounding UI (the Remove button is 30x30px, also small; the hamburger menu is 32x32px).
Fix: Increase the stepper buttons' hit area to at least 44x44px (padding can stay visually compact while the tappable area expands).
Manual timing check (iPhone 13): the header cart badge and 'Your Cart' mini-drawer are both still absent at 500ms and 1000ms after tapping 'Add to Bag', and only appear around 1500ms. In the full automated run this passed on iPhone 13 (badge='1', drawer visible by ~2.7s) but the same check on the Pixel 7 profile found neither the badge count, a toast, nor the drawer present even 2.7s after the tap. The button itself does show a lighter/disabled-looking fill briefly (a loading-state color change), but there is no spinner and the delay before the cart visibly updates is long and inconsistent enough that a real shopper could reasonably tap 'Add to Bag' a second time or assume nothing happened.
Fix: Add an immediate optimistic UI update (increment the badge and/or show a lightweight toast the instant the tap registers) while the add-to-cart network call resolves in the background, instead of waiting for the API round-trip to reflect any feedback.
Swiping the PDP gallery correctly advances the active-image indicator dot and the carousel logic is functionally correct, but the newly-active slide's <img> has loading="lazy" and is only requested at swipe time; until the network request completes (confirmed via a real 200 response) and its 300ms opacity fade-in finishes, the slide area shows a blank/empty frame. In a manual check the image was still not rendered at 800-1500ms after the swipe gesture and only settled in by ~2-3s total.
Fix: Preload the adjacent gallery image(s) once the current image has loaded, or show a low-res blur/skeleton placeholder during the lazy-load + fade-in window so a swipe never reveals an empty frame, especially over slower connections.
button[aria-label="Open menu"] measures 32x32px on both mobile profiles. It is tappable in practice (no false-negative taps observed) but sits below the recommended minimum for a primary, always-visible navigation control.
Fix: Increase the button's padding/hit-area toward 44x44px.
The metal-color, carat-weight, and ring-size chip rows on PDP all use a shared 36px-tall button style with 12px gaps. This is borderline-acceptable given the spacing, but on a dense ring-size row (19 options: 4, 4.5, 5 ... 13) the small chip height makes precise tapping a bit fiddlier than ideal.
Fix: Consider bumping chip height toward 44px, particularly for the long ring-size row, for easier thumb tapping.
The PDP 'Add to Bag' button and the cart page's quantity +/- steppers each appear twice in the DOM - one real, visible element plus a second element with an identical selector but a 0x0 bounding box (likely a hidden desktop/alternate-breakpoint variant that isn't display:none on its own element, just inside a hidden ancestor). This does not intercept real taps or cause any user-facing defect, but it does make any first-match querySelector/automation fragile and is worth cleaning up.
Fix: Low priority. Audit the responsive layout for these components and ensure hidden variants are fully removed from the DOM (or given display:none directly) rather than left as zero-size siblings.
Desktop viewports (1920x1080, 1440x900, 1366x768), hover states, keyboard navigation, layout integrity.
Clicking any top-nav item (Rings, Earrings, Necklaces, Bridal, Gifts) or any megamenu sub-link (Engagement Rings, Wedding Bands, Solitaire Rings, Halo Rings, 14K Gold, Rose Gold, White Gold, Lab Grown Diamond, Emerald Cut, Round Cut, Stud Earrings, Hoop Earrings, Drop Earrings, Diamond Earrings, Solitaire Studs, Solitaire Pendants, Diamond Pendants, Gold Chains, Tennis Necklaces) navigates to the bare-slug route (e.g. /rings) which renders 'NO PRODUCTS FOUND' / '0 Products'. Verified 15/15 sampled category slugs all return 0 products, at all 3 tested viewports. The full /products catalogue route (reached only by manually typing the URL, not linked from primary nav) correctly shows 403 real products. Network trace on /rings shows only api/menu, api/categories/all, api/categories/megamenu, and one api/ms-autocomplete/products?search= call (the header search-suggestions endpoint, called with an empty search string) — no category-scoped product-listing API call is fired at all, so the grid never even attempts to fetch matching products.
Fix: Fix the bare-slug '(www)/[slug]' route so it actually issues a Meilisearch/products query scoped to categories:<slug> (per the fleet link-convention contract) instead of only fetching menu/category metadata. This is the entire storefront's primary navigation — until fixed, a desktop shopper who uses the nav (rather than typing /products) sees zero products on every category page.
Every product's description on the PDP begins with copy such as: "Say yes in unforgettable style with JewelWeSells 0.5 Carat Round Cut Diamond Engagement Ring, crafted in premium 14K Rose Gold...". 'JewelWeSell(s)' is the fleet's known reference/competitor brand name (explicitly called out as an example to flag) and must not appear on a client storefront. Confirmed present at all 3 tested viewports (visible in the main PDP description block, not just metadata).
Fix: Find/replace 'JewelWeSell'/'JewelWeSells' out of the product-description content source (likely bulk-generated/seeded copy) across all 403 products, replacing with the theme's own brand name (Website-26) or a generic phrase, and audit for any other seeded reference-brand strings.
Every nav category's hover-flyout sub-links (By Style / By Metal / By Stone etc., ~7-10 links per category x ~5-11 categories) are present in the DOM as regular focusable <a> tags in document order, ahead of the page's actual main content. Tabbing from page load (any page, including the checkout address form) goes: WEBSITE-26 logo -> RINGS -> Engagement Rings -> Wedding Bands -> Solitaire Rings -> Halo Rings -> 14K Gold -> Rose Gold -> White Gold -> Lab Grown Diamond -> Emerald Cut -> Round Cut -> EARRINGS -> Studs -> ... continuing through every category's full submenu. Automated trace confirmed 80 consecutive Tab presses were still inside header/megamenu links (reaching only as far as the cart-bag button), and the checkout page's email/phone input fields were NOT reached even after 90 Tab presses. There is no 'skip to content' link and no mechanism to bypass the megamenu via keyboard.
Fix: Either (a) only render megamenu flyout links in the tab order when the parent trigger is focused/expanded (roving tabindex / tabindex=-1 until opened), or (b) add a visible 'Skip to content' link as the very first focusable element, or (c) restructure the megamenu as a proper disclosure widget (button + aria-expanded, Enter/Space to open, Escape to close) so keyboard users aren't forced through the entire category taxonomy before reaching page content.
At 1920x1080, 1440x900, and 1366x768, the homepage's very first content block after the thin announcement bar and header is a small 'Shop by category' icon row ('Find your sparkle'), confirmed at scrollY=0 (not a scroll artifact). There is no full-bleed hero image, lifestyle photography, brand tagline, or primary CTA button anywhere above this — unusual for a diamond/fine-jewelry storefront and a weak first impression on a large screen, which a discerning desktop shopper would expect to open with sharp hero imagery and a clear value proposition.
Fix: Add a themed hero section (lifestyle image or product macro shot, headline, subhead, CTA) above the 'Shop by category' row, sized appropriately for wide desktop viewports.
In 2 of 3 full test runs (1440x900 and 1366x768 passes), the browser console logged 'Error fetching menu: {message: Please check your internet connection and try again}' and 'Search error: {message: Please check your internet connection and try again}' during normal (non-throttled) navigation, even though the header nav and search box rendered and worked visually. This did not reproduce in the 1920x1080 run, suggesting an intermittent/flaky fetch (timeout, race condition, or transient backend hiccup) rather than a hard failure — but it is a recurring symptom worth investigating since it fires on the majority of fresh loads tested.
Fix: Review timeout/retry behavior on the api/menu and search-suggestion fetches — add retry-with-backoff or increase timeout so a slow first response doesn't surface a user-facing-adjacent console error.
The QA script's generic probe picked two already-selected, single-value option groups ('Prongs' setting and default '0.5 ct' carat) and compared their border styles — both showed the same 2px accent border because both were the (only) selected default, producing a misleading FAIL. A dedicated, targeted test on the real multi-option 'Metal Color' group (14K Rose Gold / 14K White Gold / 14K Yellow Gold) confirms the selected-state IS unambiguous: selected = 2px solid accent-pink border (rgb(255,63,108)) on a white background with dark readable text; unselected = 1px solid light-gray border (rgb(233,233,237)), same dark readable text. This is a clean PASS on the fleet's recurring 'invisible selected variant' bug pattern.
Fix: No action needed on the real variant-selection UI. If desired, harden this pattern across ALL option groups (not just Metal Color) by giving every option a `:disabled`/single-value affordance so it's visually clear when a group has only one possible value (currently 'Prongs' and default carat both display a permanent selected-looking border because there's effectively no alternative to compare against).
The three dimensions were run independently, so some findings were corrected or contradicted by a later pass. Those disagreements are recorded here rather than silently resolved — a claim below is not firm until re-verified.
The automated desktop check compared two already-selected single-option chips and reported a false FAIL. A targeted manual recheck, plus the independent mobile pass, both confirm a clean PASS: 2px accent-pink border on the selected chip vs 1px gray unselected, with readable text in both states.
Action: None — the standing PDP selected-state requirement is met on this site.