ClaudiaFix · Leona Booking

Widgets ▸ Pages for Google

Pages for Google, on your own website

Your Leona widgets are iframes. Google gives the credit for what is inside an iframe to the address it comes from (app.claudiafix.ai), not to your website. Leona can also give you real pages: one per area you serve and one per team member, with a title, a description, English and French links, structured data and a sitemap, and your booking widget inside. You show them on your own domain.

1. Set them up in Leona

  1. Settings ▸ Region: the areas you serve (each with its cities). One page is made per area. Write each area's short introduction and its questions and answers if you can: pages with your own words rank better than pages without.
  2. Settings ▸ Staff: who is shown, in which order, and what a card shows. A team page is made for each person your widgets already show. A home address, a phone, an e-mail or a travel distance is never shown. The distance a person travels and the areas they cover appear only if you switched them on for the staff card.
  3. Widgets ▸ Pages for Google:
    • Your website address, for example https://www.yourspa.com. Every page says it belongs there (its "canonical" link), so Google ranks your domain.
    • Short name, for example your-spa. It replaces your account number in our page addresses (KEY below).
    • What you do, as clients search it: "Mobile hairdresser" / "Coiffure à domicile". Area pages are titled "Mobile hairdresser in Laval".
    • Page addresses on your website: by default /areas/{slug} and /fr/secteurs/{slug} for areas, /team/{name} and /fr/equipe/{name} for people. If your website already has pages at other addresses, use those, so nothing you already rank for moves.
    • Use Preview on each page. When you are happy, switch on Publish the pages.

2. Put them on your domain — option A: a redirect rule (recommended)

Your website shows our page at your own address. It stays current by itself: a new team member or a new area appears with no work from you. Replace KEY with your short name and the paths with the ones you chose.

Vercel — in vercel.json, add these to "rewrites", before any catch-all rule such as "/(.*)":
{ "source": "/areas/:slug",        "destination": "https://app.claudiafix.ai/marketplace/public/p/KEY/en/:slug" },
{ "source": "/fr/secteurs/:slug",  "destination": "https://app.claudiafix.ai/marketplace/public/p/KEY/fr/:slug" },
{ "source": "/team",               "destination": "https://app.claudiafix.ai/marketplace/public/p/KEY/en/team" },
{ "source": "/team/:name",         "destination": "https://app.claudiafix.ai/marketplace/public/p/KEY/en/team/:name" },
{ "source": "/fr/equipe",          "destination": "https://app.claudiafix.ai/marketplace/public/p/KEY/fr/team" },
{ "source": "/fr/equipe/:name",    "destination": "https://app.claudiafix.ai/marketplace/public/p/KEY/fr/team/:name" },
{ "source": "/leona-sitemap.xml",  "destination": "https://app.claudiafix.ai/marketplace/public/p/KEY/sitemap.xml" }

If your site sets a Content-Security-Policy, allow https://app.claudiafix.ai in frame-src for these paths, or the booking widget inside the page stays blank.

Cloudflare — a Worker on the routes yourspa.com/areas/*, yourspa.com/fr/secteurs/*, yourspa.com/team*, yourspa.com/fr/equipe*, yourspa.com/leona-sitemap.xml:
const UP = "https://app.claudiafix.ai/marketplace/public/p/KEY";
const MAP = [
  [/^\/areas\/([a-z0-9-]+)\/?$/, "/en/$1"],
  [/^\/fr\/secteurs\/([a-z0-9-]+)\/?$/, "/fr/$1"],
  [/^\/team\/?$/, "/en/team"],
  [/^\/team\/([a-z0-9-]+)\/?$/, "/en/team/$1"],
  [/^\/fr\/equipe\/?$/, "/fr/team"],
  [/^\/fr\/equipe\/([a-z0-9-]+)\/?$/, "/fr/team/$1"],
  [/^\/leona-sitemap\.xml$/, "/sitemap.xml"],
];
export default {
  async fetch(req) {
    const u = new URL(req.url);
    for (const [re, to] of MAP) {
      if (re.test(u.pathname)) {
        const r = await fetch(UP + u.pathname.replace(re, to), { cf: { cacheTtl: 600 } });
        return new Response(r.body, { status: r.status, headers: r.headers });
      }
    }
    return fetch(req);
  },
};
nginx (your own server):
resolver 1.1.1.1 valid=300s;
location ~ ^/areas/([a-z0-9-]+)/?$        { proxy_pass https://app.claudiafix.ai/marketplace/public/p/KEY/en/$1;      proxy_ssl_server_name on; proxy_set_header Host app.claudiafix.ai; }
location ~ ^/fr/secteurs/([a-z0-9-]+)/?$  { proxy_pass https://app.claudiafix.ai/marketplace/public/p/KEY/fr/$1;      proxy_ssl_server_name on; proxy_set_header Host app.claudiafix.ai; }
location ~ ^/team/([a-z0-9-]+)/?$         { proxy_pass https://app.claudiafix.ai/marketplace/public/p/KEY/en/team/$1; proxy_ssl_server_name on; proxy_set_header Host app.claudiafix.ai; }
location ~ ^/fr/equipe/([a-z0-9-]+)/?$    { proxy_pass https://app.claudiafix.ai/marketplace/public/p/KEY/fr/team/$1; proxy_ssl_server_name on; proxy_set_header Host app.claudiafix.ai; }
location = /team                          { proxy_pass https://app.claudiafix.ai/marketplace/public/p/KEY/en/team;    proxy_ssl_server_name on; proxy_set_header Host app.claudiafix.ai; }
location = /fr/equipe                     { proxy_pass https://app.claudiafix.ai/marketplace/public/p/KEY/fr/team;    proxy_ssl_server_name on; proxy_set_header Host app.claudiafix.ai; }
location = /leona-sitemap.xml             { proxy_pass https://app.claudiafix.ai/marketplace/public/p/KEY/sitemap.xml; proxy_ssl_server_name on; proxy_set_header Host app.claudiafix.ai; }

Booking, team, reviews and "where we travel" pages too

The booking page, the team page, each person's page, the reviews page and the "where we travel" page also come as real pages: the title, the description, the English and French links, the structured data (your business and its Google rating, each person, the reviews, the areas) and the page's own words are in the HTML, then your live widget. With JavaScript the widget takes the words' place on screen; Google reads both. Add their rules the same way (default addresses /book · /fr/reserver, /areas · /fr/secteurs, /reviews · /fr/avis; change them under For your web person to keep the addresses you already have):

{ "source": "/book",        "destination": "https://app.claudiafix.ai/marketplace/public/p/KEY/en/book" },
{ "source": "/fr/reserver", "destination": "https://app.claudiafix.ai/marketplace/public/p/KEY/fr/book" },
{ "source": "/reviews",     "destination": "https://app.claudiafix.ai/marketplace/public/p/KEY/en/reviews" },
{ "source": "/areas",       "destination": "https://app.claudiafix.ai/marketplace/public/p/KEY/en/areas" }

Option C: your website builds its own pages (keeps your header and footer)

Add ?format=json to any page address above. The answer holds the same page in pieces: head (the title, description, robots, canonical, hreflang, Open Graph and structured-data tags, ready to put in your page's <head>), body (the page's words and the widget, ready to put where the widget goes), plus canonical, alternates, h1 and jsonld. A site that prerenders its pages (Vite, Next.js, Astro…) fetches it at build time or on each request and writes both into its own HTML: Google then reads the page with no JavaScript and no iframe, inside your own header and footer.

const r = await fetch("https://app.claudiafix.ai/marketplace/public/p/KEY/en/team?format=json").then((x) => x.json());
html = html.replace("</head>", r.head + "</head>").replace('<div id="leona"></div>', '<div id="leona">' + r.body + "</div>");

2. Or — option B: download the pages

Widgets ▸ Pages for Google ▸ Download (.zip). The file holds one folder per page, already on the address it has on your website (for example areas/laval/index.html), plus the sitemap. Upload them to your website as they are.

A downloaded copy does not change by itself. Download again and upload again after you change your team, your areas or their words. The redirect rule above never needs this.

3. Tell Google

  1. Add the two lines from https://app.claudiafix.ai/marketplace/public/p/KEY/robots.txt to your website's robots.txt (the Sitemap: line points at your own domain).
  2. In Google Search Console, submit https://www.yourspa.com/leona-sitemap.xml.
  3. Open one page on your own domain and use URL inspection ▸ Test live URL: the canonical should be your address, not app.claudiafix.ai.

Good to know