Skip to content
New: Customize your theme with an AI assistant. Read the guide

Deployment & Launch

Margo builds a static site into dist/, so it runs on any static host. It ships ready-made settings for Netlify (netlify.toml), Vercel (vercel.json, vercel.sh), and Cloudflare Pages (wrangler.toml). The site needs no account or environment variables.

SettingValue
Build commandnpm run build
Output directorydist
Node.js version22.23.4 or later
Package managernpm (package-lock.json)

Before You Launch

Go through this list once. Each item links to the page that explains it.

Address and identity

  • [site] baseUrl is your real address, not the shipped https://example.com placeholder, and npm run build shows no [site] warning (SEO & AI Visibility)
  • title, tagline, description, and logoText in [site], and author and keywords in [seo], describe you or your studio. The tagline is added to every page title. French and Arabic have their own site.tagline and site.description in src/i18n/fr.json and src/i18n/ar.json (Config Reference)
  • [seo.identity] says whether the site belongs to a Person or an Organization, with your name and, for a person, your job title
  • The logo, favicons (npm run generate-favicons), social image (npm run generate-og-image, after the two items above), colors in theme.css, and fonts in fonts.json are yours (Site Identity & Logo, Colors & Fonts)

Contact and forms

  • contactFormAction and contactFormProvider post to your own account (Formsubmit, Formspree, or Netlify Forms), and the build prints no [forms] warning (Forms)
  • The Mailchimp formAction under [settings.subscription] is your list, or enable = false there if you don’t send a newsletter
  • email and booking under [settings.contactInfo] are yours. booking is where every Book a call button goes (Contact & Booking)
  • The contact rows in src/content/sections/<language>/contact-section.md, and the email and phone in footer.md and call-to-action.md, are yours (Footer)
  • A project-wide search for example.com and 555 finds nothing you still need to change

Sample content

  • The sample projects and photo series in src/content/projects/ are replaced with your own work, and the hero cards on the homepage point to them (Projects)
  • The services, journal posts and authors, team members, testimonials, and client logos are yours or removed (Collections)
  • Every price and question on the pricing and FAQ pages is yours (Pricing & FAQ)
  • Every sample photo is replaced (Icons & Images)

Pages and menus

  • The privacy policy, terms, and cookie policy in every language folder of src/content/pages/ (privacy-policy.mdx, terms-conditions.mdx, cookie-policy.mdx) are rewritten for your practice and reviewed. They ship as sample text with a notice at the top
  • The Pages demo menu is hidden ("enable": false in every menu file), and the menus point at your pages (Menus)
  • The demo homepages you don’t use are deleted (Homepages), and /elements/ and /components/ are removed if you don’t want the layout and shortcode galleries online (Pages)
  • [settings.layoutSwitcher] enable = false, and the PUBLIC_DEMO_MODE environment variable is not set on your host
  • footer.copyright in src/i18n/<language>.json reads the way you want, and the links in src/config/social.json are yours

Analytics and checks

  • Analytics tags are in [head], marked with data-consent while the cookie banner is on (Cookies & Analytics)
  • npm run astro-check and npm run build finish without errors, and you have looked at every page whose section files you changed (astro-check doesn’t check section files or the contact, FAQ, and pricing page files)
  • The Arabic text has been reviewed by a native speaker, if you keep Arabic
  • You checked the site at phone width, in dark mode, and in every language you keep

Deploy

  1. Push your project to GitHub, GitLab, or Bitbucket.
  2. In Netlify, choose Add new site → Import an existing project and pick the repository.
  3. Netlify reads netlify.toml: build command npm run build, publish folder dist, Node.js 22. Click Deploy.

The build uses baseUrl from config.toml unless you add a SITE_URL environment variable in the Netlify site settings.

netlify.toml also sets long-term caching for /_astro/* and /images/*, and sends missing /fr/... and /ar/... URLs to that language’s 404 page. When you add a language, add its own block, as the comment in the file says.

Using Netlify Forms? Set contactFormProvider = "netlify" and contactFormAction = "/", enable form detection under Forms in the Netlify dashboard, and redeploy.

After You Launch

  1. Open the live site and click through the main pages, on a computer and on a phone, including the mobile menu, a project page, and dark mode.
  2. Send a test message through the contact form, and sign up to the newsletter if you use it, and check that both arrive.
  3. Open the search with ⌘ + K (Ctrl + K on Windows) and search for one of your projects.
  4. Click a Book a call button and check that it opens your scheduling page.
  5. Submit https://your-domain/sitemap-index.xml in Google Search Console and Bing Webmaster Tools.
  6. Check the homepage and a project page with Google’s Rich Results Test.
  7. Share a link in a chat app to check the preview image.

Tell Search Engines About Changes With IndexNow

IndexNow tells Bing, Yandex, Seznam, and Naver which pages changed, so they visit them sooner. Bing also feeds ChatGPT search and Copilot. It is off until you set a key:

  1. In config.toml, set indexNowKey under [seo.ai] to a key of 8 to 128 letters, numbers, or dashes that you make up:

    [seo.ai]
    indexNowKey = "a1b2c3d4-your-own-key"
  2. Build and deploy. The build publishes the key file at https://your-domain/<key>.txt, which the search engines check.

  3. After each deploy is live, run from your computer:

    Terminal window
    npm run build # indexnow reads the sitemap in dist/
    npm run indexnow # pages changed in the last 7 days
    npm run indexnow -- --all # every page: use it after your first launch

    npm run indexnow -- --days=30 sends the pages changed in the last 30 days, and npm run indexnow -- --dry-run lists the pages without sending them.

Updating The Live Site

With a git-connected host, every push to your main branch deploys automatically. Build locally first (npm run build) to catch errors before they reach your visitors.

Type something to search...