# Viron Portugal — tracking + mobile performance patch

Drop-in replacement files for `my-app`. Nothing was refactored and no dependency
was added: the changes use `next/script`, which already ships with Next.js.
Everything below was compiled and verified against your own source
(Next.js 16.2.4, Turbopack, `output: standalone`).

## 1. How to apply

Copy these over the matching paths in `my-app`, then rebuild and deploy:

```
app/layout.tsx              -> replaces existing file
app/page.tsx                -> replaces existing file
app/Components/Gallery.tsx  -> replaces existing file
public/*.webp               -> 10 new files, add them (keep the old PNG/JPG or delete, your call)
```

```bash
npm run build
```

`changes.diff` contains the exact line-by-line diff if you prefer to review or
apply the changes by hand.

## 2. What changed and why

### `app/layout.tsx`

- **Google Tag Manager `GTM-NMK3LZ7B`** added via `next/script`
  (`strategy="afterInteractive"`) plus the `<noscript>` iframe in `<body>`.
  The raw snippet cannot simply be pasted into this project because there is no
  `index.html`, so this is the App Router equivalent. No new dependency.
- **Meta/Facebook domain verification** added through the existing
  `export const metadata` object, as `other["facebook-domain-verification"]`.
  Next.js renders it as a normal `<meta>` tag in `<head>`.
- **`description`** added to metadata. The page had none, which PageSpeed
  flagged under SEO.

### `app/page.tsx`

- **Conversion tracking for the contact form.** This is the important one.
  The form posts through a Next.js server action, so the URL never changes and
  there is no thank-you page. Any analytics setup based on a destination URL
  would record zero leads. A `generate_lead` event is now pushed to
  `window.dataLayer` at the exact point where the server action returns success,
  right after `setBtnStatus(btnStatuses.success)`.
- **`whatsapp_click` event** on the footer WhatsApp link.
- **Hero image**: Unsplash width reduced from `w=2000&q=80` to `w=1600&q=75`
  and marked `fetchPriority="high"`. It stays eager, since it is the LCP element.
- **All other images** are now `loading="lazy" decoding="async"`. React was
  preloading five below-the-fold images in `<head>`, which is what pushed
  Largest Contentful Paint to 8.2 s on mobile.
- **Fixed two relative image paths**: `src="before1.jpg"` and `src="after1.jpg"`
  had no leading slash, so they resolved relative to the current path and would
  break on any URL other than the homepage.
- Image references updated to the new `.webp` files.

### `app/Components/Gallery.tsx`

- Gallery image references updated to `.webp`. Lazy loading was already correct.

### `public/*.webp`

Ten images re-encoded from PNG/JPEG to WebP at quality 80. Same dimensions,
no visible quality loss.

```
3488 KB  ->  1097 KB   (-68%)
```

## 3. One thing that needs the server, not the code

Static files under `/public` are served with **no `Cache-Control` header** at
all, so returning visitors re-download every image. The `_next/static` chunks
are already correct (`max-age=31536000, immutable`), only `/public` is missing.

On LiteSpeed, add to `.htaccess` at the web root:

```apache
<IfModule mod_expires.c>
  ExpiresActive On
  <FilesMatch "\.(webp|png|jpe?g|svg|ico|woff2)$">
    ExpiresDefault "access plus 1 year"
    Header set Cache-Control "public, max-age=31536000, immutable"
  </FilesMatch>
</IfModule>
```

## 4. Verified before delivery

Run against a production build of your source, in a real headless browser at a
390x844 mobile viewport:

- GTM loads: `dataLayer` receives `gtm.js`, `gtm.dom`, `gtm.load`, and a live
  request goes out to `googletagmanager.com/gtm.js`
- `<meta name="facebook-domain-verification">` renders with the correct value
- `generate_lead` fires on form success with the expected payload, and GTM
  picks it up (`gtm.uniqueEventId` assigned)
- `whatsapp_click` fires on click
- Only the hero image loads on first paint; the other ten are deferred
- `npm run build` passes, including the TypeScript check

Initial mobile page load, measured the same way on both:

```
images downloaded    1962 KB  ->  126 KB
total requests       11       ->  6
```

## 5. Security note

The zip that was shared contained `my-app/.env.local` with a live
`RESEND_API_KEY`, plus the `.git` folder and `node_modules`. That key can send
email as `info@vironportugal.com` and it has now travelled through WhatsApp.
It should be rotated in the Resend dashboard. The project's own `.gitignore`
already excludes `.env*`, so it was never meant to leave the machine.
