<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<title>SEO/GEO - AI, LLM, search engine specialist - Melbourne based</title>
<meta name="description" content="Search Engine and Generative Engine Optimization (SEO/GEO) for SMB and enterprise-level businesses. AI, LLM, search specialist, Melbourne-based." />
<link rel="preload" as="image" href="/images/hero.svg" fetchpriority="high">
<link rel="apple-touch-icon" sizes="180x180" href="/fav-icon/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/fav-icon/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/fav-icon/favicon-16x16.png">
<link rel="manifest" href="/fav-icon/site.webmanifest">
<link rel="canonical" href="https://www.andrewkeir.com/" />
<link rel="alternate" href="https://www.andrewkeir.com/" hreflang="x-default" />
<link rel="alternate" href="https://www.andrewkeir.com/" hreflang="en" />
<link rel="alternate" href="https://www.andrewkeir.com/" hreflang="en-au" />
<link rel="alternate" href="https://www.andrewkeir.com/" hreflang="en-nz" />
<link rel="alternate" href="https://www.andrewkeir.com/" hreflang="en-us" />
<link rel="alternate" href="https://www.andrewkeir.com/" hreflang="en-gb" />
<link rel="alternate" href="https://www.andrewkeir.com/" hreflang="en-za" />
<link rel="alternate" href="https://www.andrewkeir.com/" hreflang="en-ca" />
<link rel="alternate" href="https://www.andrewkeir.com/" hreflang="en-ie" />
<link rel="alternate" href="https://www.andrewkeir.com/" hreflang="en-nl" />
<link rel="alternate" href="https://www.andrewkeir.com/" hreflang="en-dk" />
<link rel="alternate" href="https://www.andrewkeir.com/" hreflang="en-se" />
<link rel="alternate" href="https://www.andrewkeir.com/" hreflang="en-no" />
<link rel="alternate" href="https://www.andrewkeir.com/" hreflang="en-fi" />
<link rel="alternate" href="https://www.andrewkeir.com/" hreflang="en-de" />
<link rel="alternate" href="https://www.andrewkeir.com/" hreflang="en-at" />
<link rel="alternate" href="https://www.andrewkeir.com/" hreflang="en-be" />
<link rel="alternate" href="https://www.andrewkeir.com/" hreflang="en-lu" />
<link rel="alternate" href="https://www.andrewkeir.com/" hreflang="en-cy" />
<link rel="alternate" href="https://www.andrewkeir.com/" hreflang="en-il" />
<link rel="preload" href="/css/bootstrap.min.css" as="style">
<!-- <link rel="preload" href="/css/main.css" as="style"> -->
<link rel="stylesheet" href="/css/bootstrap.min.css">
<!-- <link rel="stylesheet" href="/css/main.css"> -->

<!-- Scripts --><script defer src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script defer src="js/bootstrap.min.js"></script>
<!-- <script defer src="js/smooth-scroll.min.js"></script> -->
<script defer src="js/main.js"></script><!-- Scripts Ends -->
<!-- hamburger menu close --><script>document.addEventListener('DOMContentLoaded',()=>$('.navbar-nav .nav-link').on('click',function(e){const t=this.getAttribute('href'),n=$('.navbar-collapse.show');if(n.length){e.preventDefault();n.one('hidden.bs.collapse',()=>document.querySelector(t)?.scrollIntoView()).collapse('hide')}}));</script>

<!-- Commented out for removal
<link rel="preconnect" href="https://www.googletagmanager.com">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css?family=Work+Sans:400,600&display=swap" rel="stylesheet">
<link rel="stylesheet" href="icofont.min.css">
-->

<style>
/* FAQ style */
.navbar-toggler { min-width: 48px; min-height: 48px; padding: 12px; display: inline-flex; align-items: center; justify-content: center; border: 1px solid rgba(0,0,0,0.1); background: transparent; }
.navbar-toggler-icon { display: inline-block; width: 24px; height: 24px; background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.6%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e"); background-repeat: no-repeat; background-position: center; background-size: 100%; }
.navbar-nav .nav-link { min-height: 48px; padding: 12px 16px; display: flex; align-items: center; }
.qa-item { border: 1px solid #e0e0e0; border-radius: 6px; margin-bottom: 8px; background: #fff; }
.qa-item summary { list-style: none; padding: 16px 20px; background: #fafafa; font-size: 1.1rem; font-weight: 600; cursor: pointer; display: flex; justify-content: space-between; align-items: center; transition: background 0.2s; user-select: none; }
.qa-item summary::-webkit-details-marker { display: none; }
.qa-item summary:hover { background: #f0f0f0; }
.qa-item .qa-icon { font-size: 20px; font-weight: 400; flex-shrink: 0; margin-left: 12px; transition: transform 0.2s; }
.qa-item[open] .qa-icon { transform: rotate(45deg); }
.qa-item .qa-answer { padding: 16px 20px !important; font-size: 1.1rem; line-height: 1.6; border-top: 1px solid #e0e0e0; display: block !important; }
/* FAQ style END */
/* Services UL dropdown style */@media (max-width: 768px) { #services-dropdown { margin-top: 90px; } }
/* Logo carousel */
.icon-carousel { overflow: hidden; width: 100%; padding: 20px 0; -webkit-mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent); mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent); } .icon-carousel__track { display: flex; align-items: center; width: max-content; animation: icon-scroll 30s linear infinite; will-change: transform; backface-visibility: hidden; } .icon-carousel:hover .icon-carousel__track { animation-play-state: paused; } .icon-carousel__item { height: 50px; width: auto; object-fit: contain; flex-shrink: 0; margin-right: 40px; } @keyframes icon-scroll { from { transform: translate3d(0, 0, 0); } to { transform: translate3d(-50%, 0, 0); } } @media (prefers-reduced-motion: reduce) { .icon-carousel__track { animation: none; } } @media (max-width: 768px) { .brands-heading { margin-top: 100px; } }
/* Logo carousel END */
/* mobile only BR */.mobile-only { display: none; } @media (max-width: 768px) { .mobile-only { display: inline; } }
/* UL services dropdown */
ul.resp {columns: auto; column-width: 220px; column-gap: 2rem; list-style: none; padding: 0; margin-bottom: 50px;}
ul.resp li {font-size: 1.0rem;}
/* UL services dropdown END */
/* Mobile bottom menu */
.mbn { display: none; }
@media (max-width: 768px) {
.mbn { display: flex; position: fixed; bottom: 0; left: 0; right: 0; z-index: 9999; background: #fff; border-top: 1px solid #e5e5e5; padding: 6px 0 calc(6px + env(safe-area-inset-bottom)); box-shadow: 0 -2px 10px rgba(0,0,0,0.06); font-family: inherit; transform: translateY(100%); transition: transform .25s ease; pointer-events: none; }
.mbn.is-visible { transform: translateY(0); pointer-events: auto; }
.mbn-item { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; padding: 6px 2px; font-size: 10.5px; color: #555; text-decoration: none; min-height: 44px; transition: color .15s ease; }
.mbn-item svg { width: 22px; height: 22px; }
.mbn-item.active { color: #0066cc; }
body { padding-bottom: calc(68px + env(safe-area-inset-bottom)); }}
/* Mobile bottom menu END */
</style>

<!-- Google Tag Manager (deferred) --><script>
  window.dataLayer = window.dataLayer || [];
  (function() {
    var gtmLoaded = false;
    function loadGTM() {
      if (gtmLoaded) return;
      gtmLoaded = true;
      window.dataLayer.push({'gtm.start': new Date().getTime(), event: 'gtm.js'});
      var f = document.getElementsByTagName('script')[0];
      var j = document.createElement('script');
      j.async = true;
      j.src = 'https://www.googletagmanager.com/gtm.js?id=GTM-KWVC6BB';
      f.parentNode.insertBefore(j, f);
    }
    ['scroll', 'mousemove', 'touchstart', 'keydown', 'click'].forEach(function(e) {
      window.addEventListener(e, loadGTM, { once: true, passive: true });
    });
    setTimeout(loadGTM, 2000);
  })();
</script><!-- End Google Tag Manager (deferred) -->
	
</head>
<body>
<main>

<!-- Header section -->  
<header id="home">
<div class="container">
<nav class="navbar navbar-expand-lg navbar-light ">
<!-- comment out logo <a class="navbar-brand" href="#"><img src="images/logo.svg" alt=""></a> -->
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active"><a class="nav-link" data-scroll href="#home">Home<span class="sr-only">(current)</span></a></li>
<li class="nav-item"><a class="nav-link" data-scroll href="#seo-geo">Services</a></li>
<li class="nav-item"><a class="nav-link" data-scroll href="#full-stack">Full-stack SEO</a></li>
<li class="nav-item"><a class="nav-link" data-scroll href="#faq">FAQs</a></li>
<li class="nav-item"><a class="nav-link" data-scroll href="#contact-us">Contact</a></li>
</ul>
</div>
<script>
  const nav = document.getElementById('mobile-bottom-nav');
  window.addEventListener('scroll', () => {
    if (window.scrollY > 80) {
      nav.classList.add('visible');
    } else {
      nav.classList.remove('visible');
    }
  });
</script>
</nav>
</div>

<!-- Hero section -->    
<div class="container-fluid hero">
<img src="/images/hero.svg" alt="SEO and GEO" width="925" height="987" fetchpriority="high">
<div class="container">
<h1>SEO/GEO specialist</h1>
<div style="max-width:630px;"><p>I'm Andrew Keir, an SEO consultant and online marketing strategist with 15 years' experience, providing comprehensive Search Engine Optimization (SEO) and Generative Engine Optimization (GEO) for SMB and enterprise-level businesses. Based in Melbourne, working with clients worldwide.</p></div>
<div class="hero-btns">
<!-- Hero Btn First --><a data-scroll href="#seo-geo">Services</a>
<!-- Hero Btn Second --><a data-scroll href="#contact-us">Get in touch</a>
</div>
</div>
</div>
</header>
<!-- Header section END-->  

<!-- Services section -->
<section class="about" style="margin-bottom:100px;"><div class="container"><div class="row"><div class="col-12 col-sm-12 col-lg-6">
<img src="images/aboutimg.svg" alt="" width="627" height="375">
</div>
<div class="col-12 col-sm-12 col-lg-6">
<h2 id="seo-geo" class="h5">Search engine and generative engine optimization</h2>
<h3 class="h2">AI, LLM and organic search optimization</h3>
<p>Analysis of your current rankings and traffic, identification of missed opportunities, and areas for improvement, to boost your website's presence in organic search, as well as mentions and citations in AI and large language models (LLMs) like ChatGPT, Google AI Overviews, Claude, and more; for national, international, and local businesses.</p>
</div>
</div></div></section>
<!-- Services section END-->

<!-- Full-stack section -->
<section id="full-stack" class="services">
<div class="container-fluid">
<div class="side-img"><img src="images/aside.svg" alt="background"></div>
<div class="side2-img"><img src="images/aside2.svg" alt="background"></div>
<div class="container">
<div class="row">
<div class="col-12 col-sm-12 col-lg-4 service-txt">
<h2>Full-stack SEO</h2>
<p style="font-size: 1.1rem; margin-bottom:50px;">Tired of "SEOs" that just fiddle with titles and descriptions? <br><br>I can provide a lot more.</p>
<div class="hero-btns">
<!-- Hero Btn First --><a data-scroll href="#contact-us">Contact me</a>
<!-- Hero Btn Second --><a data-scroll href="#contact-us" style="display:none;"></a>
</div>
</div>
<div class="col-12 col-sm-6 col-lg-4">
<div class="service-box">
<img src="images/service-icon2.svg" alt="" width="56" height="57">
<h3>Technical</h3>
<p>I can work with your web developer, or provide developer services, to optimize your website's efficiency, server performance, and implement optimizations for SEO and GEO on a variety of CMS platforms.</p>
</div>
</div>
<div class="col-12 col-sm-6 col-lg-4">
<div class="service-box">
<img src="images/service-icon1.svg" alt="" width="64" height="47">
<h3>Content</h3>
<p>I can provide content, or work with your copywriters and designers to optimize copy, images, metadata, schema, structured data, user experience, conversion rates, and more.</p>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- Full-stack section END-->

<!-- Logo carousel --><section id="carousel" class="contact" style="margin-bottom:110px;"><div class="container"><div class="row"><div class="col-12">

<h2 class="brands-heading" style="text-align:center;">Brands I've worked on</h2>
<div class="icon-carousel" aria-label="Brands">
  <div class="icon-carousel__track">
    <!-- Set 1 -->
    <img class="icon-carousel__item" src="/images/brands/logo-1.jpg" alt="Brand 1" width="142" height="50" loading="lazy" decoding="async">
    <img class="icon-carousel__item" src="/images/brands/logo-2.jpg" alt="Brand 2" width="50" height="50" loading="lazy" decoding="async">
<!--    <img class="icon-carousel__item" src="/images/brands/logo-3.jpg" alt="Brand 3" width="150" height="50" loading="lazy" decoding="async"> -->
    <img class="icon-carousel__item" src="/images/brands/logo-5.jpg" alt="Brand 5" width="160" height="50" loading="lazy" decoding="async">
    <img class="icon-carousel__item" src="/images/brands/logo-6.jpg" alt="Brand 6" width="81" height="50" loading="lazy" decoding="async">
    <img class="icon-carousel__item" src="/images/brands/logo-7.jpg" alt="Brand 7" width="175" height="50" loading="lazy" decoding="async">
<!--    <img class="icon-carousel__item" src="/images/brands/logo-8.jpg" alt="Brand 8" width="60" height="50" loading="lazy" decoding="async"> -->
	<img class="icon-carousel__item" src="/images/brands/logo-12.jpg" alt="Brand 12" width="52" height="50" loading="lazy" decoding="async">
    <img class="icon-carousel__item" src="/images/brands/logo-9.jpg" alt="Brand 9" width="240" height="50" loading="lazy" decoding="async">
    <img class="icon-carousel__item" src="/images/brands/logo-4.jpg" alt="Brand 4" width="56" height="50" loading="lazy" decoding="async">
    <img class="icon-carousel__item" src="/images/brands/logo-10.jpg" alt="Brand 10" width="243" height="50" loading="lazy" decoding="async">
    <img class="icon-carousel__item" src="/images/brands/logo-11.jpg" alt="Brand 11" width="50" height="50" loading="lazy" decoding="async">
    <!-- Set 2 (duplicate for seamless loop) -->
    <img class="icon-carousel__item" src="/images/brands/logo-1.jpg" alt="" aria-hidden="true" width="142" height="50" loading="lazy" decoding="async">
    <img class="icon-carousel__item" src="/images/brands/logo-2.jpg" alt="" aria-hidden="true" width="50" height="50" loading="lazy" decoding="async">
<!--    <img class="icon-carousel__item" src="/images/brands/logo-3.jpg" alt="" aria-hidden="true" width="150" height="50" loading="lazy" decoding="async"> -->
    <img class="icon-carousel__item" src="/images/brands/logo-5.jpg" alt="" aria-hidden="true" width="160" height="50" loading="lazy" decoding="async">
    <img class="icon-carousel__item" src="/images/brands/logo-6.jpg" alt="" aria-hidden="true" width="81" height="50" loading="lazy" decoding="async">
    <img class="icon-carousel__item" src="/images/brands/logo-7.jpg" alt="" aria-hidden="true" width="175" height="50" loading="lazy" decoding="async">
<!--    <img class="icon-carousel__item" src="/images/brands/logo-8.jpg" alt="" aria-hidden="true" width="60" height="50" loading="lazy" decoding="async"> -->
    <img class="icon-carousel__item" src="/images/brands/logo-12.jpg" alt="" aria-hidden="true" width="52" height="50" loading="lazy" decoding="async">
    <img class="icon-carousel__item" src="/images/brands/logo-9.jpg" alt="" aria-hidden="true" width="240" height="50" loading="lazy" decoding="async">
    <img class="icon-carousel__item" src="/images/brands/logo-4.jpg" alt="" aria-hidden="true" width="56" height="50" loading="lazy" decoding="async">
    <img class="icon-carousel__item" src="/images/brands/logo-10.jpg" alt="" aria-hidden="true" width="243" height="50" loading="lazy" decoding="async">
    <img class="icon-carousel__item" src="/images/brands/logo-11.jpg" alt="" aria-hidden="true" width="50" height="50" loading="lazy" decoding="async">
  </div>
</div>

</div></div></div></section><!-- Logo carousel END-->

<!-- FAQ -->
<section id="faq" class="contact"><div class="container"><div class="row"><div class="col-12">
<div class="qa-accordion" style="margin-bottom:100px;">
<span class="h2">FAQs </span><br class="mobile-only"><span class="h5" style="margin:10px 0 50px 0; display:inline-block;">Ready to talk? <a style="text-decoration:underline; color:#FF3946;" href="#contact-us" onmouseover="this.style.color='#314584'" onmouseout="this.style.color='#FF3946'">Skip the FAQs</a></span>

<details class="qa-item"><summary><span>What is a realistic timeline to see results?</span><span class="qa-icon">+</span></summary><div class="qa-answer">Growing organic traffic means 'playing the long game', you won't see results in just a few weeks. I recommend a minimum campaign length of 3 months, but ultimately the goal is delivering year-on-year growth over the long term.</div></details>
<details class="qa-item"><summary><span>How do you structure your pricing (retainer, project-based, hourly)?</span><span class="qa-icon">+</span></summary><div class="qa-answer">A monthly retainer is standard, this is the best approach keeping pace with the evolving nature of organic search and AI/LLMs.</div></details>
<details class="qa-item"><summary><span>How do you measure success, and what KPIs do you track?</span><span class="qa-icon">+</span></summary><div class="qa-answer">KPIs and conversion tracking can be set for almost anything: phone calls, emails, contact form submissions, live chat, whatever matters most to your business.</div></details>
<details class="qa-item"><summary><span>Have you worked with businesses in my industry before?</span><span class="qa-icon">+</span></summary><div class="qa-answer">I have worked with businesses across a wide range of industries including finance, construction, healthcare, retail, hospitality, tradespeople, SaaS, charities, and a range of professional services. Whatever your business, I can help.</div></details>
<details class="qa-item"><summary><span>Will you be doing the work, or outsourcing it?</span><span class="qa-icon">+</span></summary><div class="qa-answer">I will be doing the work. In specific cases, some specialist tasks may involve a third party, but your overall campaign won't be outsourced.</div></details>
<details class="qa-item"><summary><span>Is there a minimum contract period?</span><span class="qa-icon">+</span></summary><div class="qa-answer">No long term contracts are required. Services are month-to-month with 14 days' notice required for any changes.</div></details>
<details class="qa-item"><summary><span>Do you handle content creation, or just technical SEO?</span><span class="qa-icon">+</span></summary><div class="qa-answer">Both. I cover end-to-end optimisation including back-end technical requirements, CMS management, and front-end content.</div></details>
</div>

<!-- FAQ Schema -->
<script type="application/ld+json">
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://www.andrewkeir.com/#faq","url":"https://www.andrewkeir.com/","mainEntity":[
{"@type":"Question","name":"What is a realistic timeline to see results?","acceptedAnswer":{"@type":"Answer","text":"Growing organic traffic means 'playing the long game', you won't see results in just a few weeks. I recommend a minimum campaign length of 3 months, but ultimately the goal is delivering year-on-year growth over the long term."}},
{"@type":"Question","name":"How do you structure your pricing (retainer, project-based, hourly)?","acceptedAnswer":{"@type":"Answer","text":"A monthly retainer is standard, this is the best approach keeping pace with the evolving nature of organic search and AI/LLMs."}},
{"@type":"Question","name":"How do you measure success, and what KPIs do you track?","acceptedAnswer":{"@type":"Answer","text":"KPIs and conversion tracking can be set for almost anything: phone calls, emails, contact form submissions, live chat, whatever matters most to your business."}},
{"@type":"Question","name":"Have you worked with businesses in my industry before?","acceptedAnswer":{"@type":"Answer","text":"I have worked with businesses across a wide range of industries including finance, construction, healthcare, retail, hospitality, tradespeople, SaaS, charities, and a range of professional services. Whatever your business, I can help."}},
{"@type":"Question","name":"Will you be doing the work, or outsourcing it?","acceptedAnswer":{"@type":"Answer","text":"I will be doing the work. In specific cases, some specialist tasks may involve a third party, but your overall campaign won't be outsourced."}},
{"@type":"Question","name":"Is there a minimum contract period?","acceptedAnswer":{"@type":"Answer","text":"No long term contracts are required. Services are month-to-month with 14 days' notice required for any changes."}},
{"@type":"Question","name":"Do you handle content creation, or just technical SEO?","acceptedAnswer":{"@type":"Answer","text":"Both. I cover end-to-end optimisation including back-end technical requirements, CMS management, and front-end content."}}
]}
</script>
<!-- FAQ Schema END-->

</div></div></div></section>
<!-- FAQ END-->

<!-- Contact me -->
<section id="contact-us" class="contact" style="margin-top:15px;"><div class="container"><div class="row"><div class="col-12">
<p class="h5">Contact me</p>
<p class="h2">Book a free consultation</p>
<p style="margin-bottom:50px;">To discuss your website strategy and growth plan, <a target="_blank" data-scroll href="https://docs.google.com/forms/d/e/1FAIpQLSd6M6Av_wG0zz0aJ1NgcUyLcokV9acdeqySJ2uD-fda63xFAQ/viewform?usp=header" onmouseover="this.style.color='#FF3946'" onmouseout="this.style.color=''"><u>book a free consultation</u></a> by clicking the button below.</p><br>
<div class="hero-btns">
<!-- Hero Btn First --><a target="_blank" data-scroll href="https://docs.google.com/forms/d/e/1FAIpQLSd6M6Av_wG0zz0aJ1NgcUyLcokV9acdeqySJ2uD-fda63xFAQ/viewform?usp=header">Enquire now</a>
<!-- Hero Btn Second --><a data-scroll href="#contact-us" style="display:none;"></a>
</div>
</div></div></div></section>
<!-- Contact me END-->

<!-- UL style and script -->
<section id="services-dropdown" class="contact"><div class="container"><div class="row"><div class="col-12">
<script>
  function toggleDiv(id) {
    const div = document.getElementById(id);
    div.style.display = div.style.display === 'none' ? 'block' : 'none';
  }
</script>
<!-- UL style and script END -->
<!-- Services UL -->
<p style="font-size: 1.0rem;"><a href="#" onclick="toggleDiv('services-ul'); return false;">Toggle SEO list:</a></p>
<div id="services-ul" style="display:none;">
<ul class="resp">
<li>.htaccess</li>
<li>404 pages</li>
<li>4xx errors</li>
<li>Alt text</li>
<li>Anchor text</li>
<li>Broken links</li>
<li>Canonical management</li>
<li>Compression</li>
<li>Cloudflare</li>
<li>Duplicate URIs</li>
<li>Google Analytics</li>
<li>Google My Business</li>
<li>Google Search Console</li>
<li>Google Tag Manager</li>
<li>Gzip</li>
<li>Hreflang localization</li>
<li>HTML markup</li>
<li>HTTPS/HTTP mixed content</li>
<li>Image optimisation</li>
<li>Internal linking</li>
<li>JS/CSS minification</li>
<li>Lazy loading</li>
<li>Local SEO</li>
<li>Metadata and directives</li>
<li>nofollow directives</li>
<li>noindex directives</li>
<li>Online directory listings</li>
<li>Open Graph protocol</li>
<li>Page indexing</li>
<li>Pagespeed insights</li>
<li>Pagination</li>
<li>Permalinks</li>
<li>Query strings</li>
<li>Redirect management</li>
<li>Robots.txt</li>
<li>Schema/Structured data</li>
<li>Sitemaps</li>
<li>URI handling</li>
<li>Web taxonomy</li>
</ul>

<!-- Schema UL -->
<p style="font-size: 1.0rem;"><a href="#" onclick="toggleDiv('schema-ul'); return false;">Toggle schema list:</a></p>
<div id="schema-ul" style="display:none;">
<ul class="resp">
<li>WebPage</li>
<li>Breadcrumb</li>
<li>FAQpage</li>
<li>LocalBusiness</li>
<li>serviceArea</li>
<li>Organization</li>
<li>ContactPage</li>
<li>Article</li>
<li>CollectionPage</li>
<li>HowTo</li>
<li>Service</li>
<li>Video</li>
<li>Person</li>
<li>Event</li>
<li>Product</li>
<li>Offer</li>
<li>SearchAction</li>
<li>sameAs</li>
<li>termsOfService</li>
</ul>
</div><!-- Schema UL END -->

</div><!-- Services UL END -->
			
</div></div></div></section>

<!-- Blue footer strip -->
<div style="width:100vw; min-height:30px; background-color:#314584;"></div>

<!-- General schema -->
<script type="application/ld+json">
{"@context":"https://schema.org","@graph":[
{"@type":"WebPage","@id":"https://www.andrewkeir.com/#webpage","url":"https://www.andrewkeir.com/","name":"SEO/GEO Consultant – Andrew Keir","description":"Andrew Keir is a Melbourne-based SEO and GEO optimization specialist providing comprehensive Search Engine Optimization and Generative Engine Optimization services for SMB and enterprise businesses.","inLanguage":"en-AU","isPartOf":{"@id":"https://www.andrewkeir.com/#website"}},
{"@type":"WebSite","@id":"https://www.andrewkeir.com/#website","url":"https://www.andrewkeir.com/","name":"Andrew Keir – SEO/GEO Consultant","inLanguage":"en-AU","publisher":{"@id":"https://www.andrewkeir.com/#person"}},
{"@type":"Person","@id":"https://www.andrewkeir.com/#person","name":"Andrew Keir","url":"https://www.andrewkeir.com/","jobTitle":"SEO/GEO Consultant","description":"Online marketing strategist specialising in Search Engine Optimization (SEO) and Generative Engine Optimization (GEO) for SMB and enterprise-level businesses.","address":{"@type":"PostalAddress","addressLocality":"Melbourne","addressRegion":"VIC","addressCountry":"AU"},"knowsAbout":["Search Engine Optimization","Generative Engine Optimization","Technical SEO","Content Optimization","Schema Markup","Structured Data","Google Analytics","Search Console","Google Tag Manager","Sitemaps","Robots.txt","Canonical Management","Redirect Management","Hreflang Localization","Open Graph Protocol","Pagespeed Optimization","Internal Linking","Image Optimisation","Google My Business"]},
{"@type":"ProfessionalService","@id":"https://www.andrewkeir.com/#business","name":"Andrew Keir – SEO/GEO Consultant","url":"https://www.andrewkeir.com/","logo":"https://www.andrewkeir.com/images/hero.svg","address":{"@type":"PostalAddress","addressLocality":"Melbourne","addressRegion":"VIC","addressCountry":"AU"},"areaServed":{"@type":"Country","name":"Australia"},"founder":{"@id":"https://www.andrewkeir.com/#person"},"hasOfferCatalog":{"@type":"OfferCatalog","name":"SEO & GEO Services","itemListElement":[{"@type":"Offer","itemOffered":{"@type":"Service","name":"Technical SEO","description":"Technical website optimization including Google Analytics, Search Console, Google Tag Manager, sitemaps, robots.txt, .htaccess, URI handling, canonical management, redirect management, page indexing, broken links, 404 pages, 4xx errors, noindex directives, nofollow directives, duplicate URIs, permalinks, web taxonomy, pagination, metadata and directives, hreflang localization, Open Graph protocol, HTML markup, internal linking, anchor text, image optimisation, alt text, Google My Business, directory listings, HTTPS/HTTP mixed content, Pagespeed Insights, JS/CSS minification, compression, lazy loading, and schema/structured data."}},{"@type":"Offer","itemOffered":{"@type":"Service","name":"Schema & Structured Data Implementation","description":"Implementation of structured data types including WebPage, Breadcrumb, FAQPage, LocalBusiness, serviceArea, Organization, ContactPage, Article, CollectionPage, HowTo, Service, Video, Person, Event, Product, Offer, termsOfService, SearchAction (Sitelinks box), and sameAs."}},{"@type":"Offer","itemOffered":{"@type":"Service","name":"Content Optimization","description":"Optimization of copy, images, metadata, schema, structured data, website design, user experience, and conversion rates."}},{"@type":"Offer","itemOffered":{"@type":"Service","name":"Generative Engine Optimization (GEO)","description":"Optimization for AI and large language model mentions and citations in services such as ChatGPT, Google AI Overview, Claude, and more."}}]}},
{"@type":"ContactPage","@id":"https://www.andrewkeir.com/#contact","url":"https://docs.google.com/forms/d/e/1FAIpQLSd6M6Av_wG0zz0aJ1NgcUyLcokV9acdeqySJ2uD-fda63xFAQ/viewform?usp=header","name":"Book a Free Consultation – Andrew Keir","description":"Book a free consultation and discovery call to discuss your website strategy and growth plan."},
{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://www.andrewkeir.com/"}]}
]}
</script>
<!-- General schema END -->

<!-- Org schema -->
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Organization",
  "@id": "https://www.andrewkeir.com/#organization",
  "name": "Andrew Keir",
  "url": "https://www.andrewkeir.com/",
  "logo": {
    "@type": "ImageObject",
    "url": "https://www.andrewkeir.com/fav-icon/apple-touch-icon.png",
    "width": 180,
    "height": 180
  },
  "description": "Melbourne-based SEO and Generative Engine Optimization (GEO) consultant providing search engine and AI/LLM optimization for SMB and enterprise businesses.",
  "foundingLocation": {
    "@type": "Place",
    "name": "Melbourne, VIC, Australia"
  },
  "address": {
    "@type": "PostalAddress",
    "addressLocality": "Melbourne",
    "addressRegion": "VIC",
    "addressCountry": "AU"
  },
  "areaServed": [
    { "@type": "Country", "name": "Australia" },
    { "@type": "Country", "name": "New Zealand" },
    { "@type": "Country", "name": "United Kingdom" },
    { "@type": "Country", "name": "United States" },
    { "@type": "Country", "name": "Canada" },
    { "@type": "Country", "name": "Ireland" }
  ]
}
</script>
<!-- Org schema END -->

<!-- Floating portrait -->
<!--
<div class="floating-portrait">
  <img src="/images/portrait.png" alt="SEO" />
</div>

<style>
  .floating-portrait {
    position: fixed;
    bottom: 0;
    right: 32px;
    width: 350px;
    z-index: 999;
    animation: slideUp 0.6s cubic-bezier(0.22, 1, 0.36, 1) forwards;
  }

  .floating-portrait img {
    display: block;
    width: 100%;
    border-radius: 8px 8px 0 0;
  }

  @keyframes slideUp {
    from {
      transform: translateY(100%);
      opacity: 0;
    }
    to {
      transform: translateY(0);
      opacity: 1;
    }
  }

  @media (max-width: 768px) {
    .floating-portrait {
      display: none;
    }
  }
</style>
-->

<!-- Empty container duplicate
<section id="IDHERE" class="contact" style="display:none;"><div class="container"><div class="row"><div class="col-12">

</div></div></div></section>
Empty container duplicate END -->

</main>

<!-- Mobile bottom nav --><nav class="mbn" aria-label="Mobile navigation">
<a href="#home" class="mbn-item" data-target="home"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12l9-9 9 9M5 10v10h14V10"/></svg><span>Home</span></a>
<a href="#seo-geo" class="mbn-item" data-target="seo-geo"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="7"/><path d="M21 21l-4.3-4.3"/></svg><span>Services</span></a>
<a href="#full-stack" class="mbn-item" data-target="full-stack"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="5" rx="1"/><rect x="3" y="10" width="18" height="5" rx="1"/><rect x="3" y="16" width="18" height="5" rx="1"/></svg><span>Full-stack</span></a>
<a href="#faq" class="mbn-item" data-target="faq"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M9.5 9a2.5 2.5 0 015 0c0 1.5-2.5 2-2.5 4"/><circle cx="12" cy="17" r=".5" fill="currentColor"/></svg><span>FAQs</span></a>
<a href="#contact-us" class="mbn-item" data-target="contact-us"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 6h16v12H4z"/><path d="M4 6l8 7 8-7"/></svg><span>Contact</span></a>
</nav><!-- Mobile bottom nav END -->

<!-- Mobile bottom nav script --><script>!function(){function t(){var t=document.querySelector(".mbn");if(t){var e=t.querySelectorAll(".mbn-item");if(e.length){var n=[];e.forEach(function(t){var e=t.getAttribute("data-target");if(e){var i=document.getElementById(e);i&&n.push({el:i,link:t})}});var i=function(){if(t&&t.classList){if(window.matchMedia("(min-width: 769px)").matches)return void t.classList.remove("is-visible");window.scrollY>100?t.classList.add("is-visible"):t.classList.remove("is-visible");if(n.length){var i=window.scrollY+.35*window.innerHeight,o=n[0];n.forEach(function(t){t.el&&t.el.offsetTop<=i&&(o=t)}),e.forEach(function(t){t&&t.classList&&t.classList.remove("active")}),o&&o.link&&o.link.classList&&o.link.classList.add("active")}}};window.addEventListener("scroll",i,{passive:!0}),window.addEventListener("resize",i),i()}}}"loading"===document.readyState?document.addEventListener("DOMContentLoaded",t):t()}();</script><!-- Mobile bottom nav script END-->

<!-- GTM (noscript) --><noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-KWVC6BB" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript><!-- End GTM (noscript) -->

</body>
</html>