Technical & Structure · 9 min read · September 25, 2026 · Hafsa Tariq, gaash.ai
A landscaping website AI can read: from photo gallery to project records
Turn the gallery into project records. Each job worth showing gets a page that says, in text, the town, the job, its size and season, the materials and plants by name, what the yard was before and any permit you pulled, with a caption under every photo and a link to its service. The markup then describes the business and its services, and only what the pages say.
What a crawler receives from a gallery or a before-and-after slider
When a gallery or a before-and-after slider is built by a script in the browser, the page arrives as an empty container and a script tag, and the photos, their captions and the slider exist only after the script runs. A fetcher that runs no scripts gets the container. For the assistants' fetchers, usually no scripts run: Google renders JavaScript as a separate, deferred step, and the assistants' crawler documentation promises no rendering at all.
In our audit of 9,483 small business websites (40 trades, 90 metros, late August to early September 2026), 3.0% delivered their content only through JavaScript, and our crawler, which ran no scripts, received an empty page from each. The figure covers every trade; we publish no landscaping or gallery cut of it.
The slider is the landscaping case to check first. A before-and-after pair is the photo that proves the job, and when a script builds it, neither image nor the date under it is in the HTML. Open a project page with scripts turned off, or view its source, and look for the photos' file addresses and the words under them. If they are missing, ask whether the plugin can read images already in the page's HTML instead of loading its own; if it cannot, put the pair on the page as two ordinary photos with captions and let the slider sit beside them. The portfolio article goes through the other gallery builds, lightboxes and file names one by one.
A project record for a landscaping job, field by field
A project record is a page for one job, with the facts a homeowner asks about stated in text. The gallery answers one question, whether you do good work. The record answers the ones that decide a call: have you built this, at this size, in my town, on a yard like mine.
| Field | What the record states | The question it answers |
|---|---|---|
| The job | The service by the name your service page uses: paver patio, retaining wall, sod, drip irrigation, spring cleanup contract | "Have you built one?" |
| The town | The town or the neighborhood; never the street or the house number | "Have you worked near me?" |
| Size | Square feet of patio, length and height of wall, area of sod, the number of irrigation zones | "Can you do one this big?" |
| Season and dates | The month the work started and finished, and the date of each photo | "When would mine be done?" |
| The site before | The slope, the drainage, the soil and the shade, and what came out: an old patio, a failing wall, a lawn | "Can you deal with a yard like mine?" |
| Materials by name | The paver or stone line and color as the supplier names them, the base, the edging, the wall system, the mulch | "Do you work with [material]?" |
| Plants by name | Each plant's common name and botanical name, its size at planting and how many | "Who plants [plant] around here?" |
| The permit | Only if you pulled one: its type and number, and the office that issued it, as the office wrote them | "Do you handle the permit?" |
| The service | A link to the service page, and one back to the record from the service page | "What does a job like this cost?" |
| Aftercare | A link to the care instructions the customer was given | "What will I have to do afterwards?" |
Open the record with a sentence that holds the job, the size, the place and the date: "[Company] built a [size] [material] patio with a [height] seat wall in [neighborhood], [town], in [month year], on a lawn that sloped toward the house." If that is the only sentence anyone lifts from the page, it still says who did what, where and when, which is the whole of what citability asks of it.
Plants get both names because a common name can change from one region to the next, while a botanical name is the same everywhere. "[Common name] ([botanical name]), [number] at [size]" lets a homeowner who asks for a plant by either name find the job that used it, and tells a reader in another town exactly which plant you mean.
The permit field is a fact about your job, not a statement of the rules. Whether a patio, a wall or an irrigation tie-in needs a permit is decided by the office that issues them and differs by jurisdiction, so the record states what you did ("Permit [number], issued by [office], [month year]") and nothing about what the reader's job will need. A license or certification named on the record is written the same way, as the issuing body writes it. For client permission and privacy, documenting reference projects sets out what to ask before a job goes on the site.
A caption under every photo, and alt text that describes the frame
A photo shows the yard. It cannot say which month it was taken or how long after the install, and those are the facts a landscaping photo exists to prove. So every photo in a record gets a visible caption that states them: "After, [month year], one season on: [size] [material] patio, [plant] along the wall." A caption is text on the page, which every reader sees and a fetcher receives with the rest of the HTML.
Alt text does a different job. It stands in for the photo for someone who cannot see it, so it describes what is in the frame, not the date or the job. The HTML standard's section on images sets out what the alt attribute is for. Written side by side for a before-and-after pair, the two seldom say the same thing.
| Photo | Caption, visible on the page | Alt text |
|---|---|---|
| Before | Before, [month year]: the lawn sloped toward the foundation and held water after rain | A sloping lawn running down to a house wall, with standing water along the foundation |
| After | After, [month year]: [size] [material] patio with a [height] seat wall and a drain along the house | A stone patio with a low curved wall, two chairs and a planted bed along the house |
Where the records sit: under their service, not under a town
Each record links to the service it belongs to, and each service page lists its records by town and year: "Patios we have built: [town], [year]; [town], [year]; [town], [year]." That list answers "have you done a patio in [town]" with evidence, and every entry on it is a job that happened.
It is also the honest answer to the town-page question. A page per town with the same paragraph and the name swapped is what Google's spam policies give as an example of doorway abuse, and the route-map check sets out why a missing town belongs in the service-area list instead. A record names a town because the crew worked there, and the landscaping and lawn care page covers what the service pages themselves state.
Markup for the business and each service, matching the pages
schema.org has no landscaping type. LocalBusiness has a subtype, HomeAndConstructionBusiness, for businesses that provide services around homes and buildings, and its more specific types (Electrician, GeneralContractor, HVACBusiness, HousePainter, Locksmith, MovingCompany, Plumber, RoofingContractor) include none for landscaping. So the business node is a HomeAndConstructionBusiness, and schema.org notes that such a business can be described as the provider of one or more Service nodes.
In our audit, 17.8% of the sites carried no schema.org markup at all, and most of what the rest carried described the website (WebSite, WebPage, BreadcrumbList, SearchAction, ImageObject) rather than the business. LocalBusiness appeared on roughly a quarter of the sites, and a further 13.7% had business markup missing the fields that would make it usable. Those figures are sample-wide, with no landscaping cut.
The graph below, written as JSON-LD, has one business node with an @id, placed once on the site, and one Service node on each service page, pointing back to the business as its provider. areaServed on the business lists the route's towns; on a service, it lists only the towns where that service runs, if that is fewer. Add openingHoursSpecification for the office hours if the contact page states them. Building an entity explains the @id graph in more depth.
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "HomeAndConstructionBusiness",
"@id": "https://www.example.com/#business",
"name": "[Company name, as on the trucks and the signage]",
"url": "https://www.example.com/",
"telephone": "[the one number on every page]",
"address": {
"@type": "PostalAddress",
"addressLocality": "[the town you work from]",
"addressRegion": "[state or province]",
"addressCountry": "[two-letter country code]"
},
"areaServed": [
{ "@type": "City", "name": "[town on the route]" },
{ "@type": "City", "name": "[town on the route]" },
{ "@type": "City", "name": "[town on the route]" }
]
},
{
"@type": "Service",
"@id": "https://www.example.com/irrigation/#service",
"name": "Irrigation installation and repair",
"serviceType": "Irrigation",
"url": "https://www.example.com/irrigation/",
"provider": { "@id": "https://www.example.com/#business" },
"areaServed": [
{ "@type": "City", "name": "[town where you do irrigation]" }
]
}
]
}Put nothing in the markup that the page does not show. Google's introduction to structured data says not to mark up information a visitor cannot see, and its local business documentation lists the address among the required properties. If your pages show only the town you work from, the address in the markup says only that too, because the markup follows the page.
A project record needs no business node of its own; where its markup mentions the business, it points at the @id. Its photos can carry ImageObject nodes with the caption and the town the page shows, as the portfolio article describes. Google's general structured data guidelines add that markup enables a feature but does not guarantee that it will appear, even when the markup is correct.
Common questions
Do we have to replace our gallery plugin?
Not if it can read photos and captions that are already in the page's HTML. Check a project page with scripts turned off: if the photos' addresses and the captions are there, the plugin only adds the slider on top. If the page is empty without scripts, put the photos and captions in the page as ordinary HTML and let the plugin sit beside them, or ask its maker for a setting that does this.
Should a project record name the client or the street?
Name the client only if they agree, and the street never. The town or the neighborhood is what another homeowner looks for, while a street and a house number point at someone's home. Ask the client before the record goes up, keep the answer with the job file, and take the record down or remove a detail whenever they ask.
Most of our jobs need no permit. Should the record say so?
Leave the field out. It exists for the jobs where you pulled one, stated as the issuing office wrote it. "No permit needed" is a statement about the rules, which differ by jurisdiction and are the issuing office's to state, not a fact about your job. A customer who asks whether their own job needs one should get that answer from the office.
Can our Google rating go in the business markup?
No. Google's review snippet rules say not to aggregate reviews or ratings from other websites, and a business that controls the reviews about itself is not eligible for review stars. Put two or three real reviews on the page as text instead, each with the reviewer's first name, the date and the platform, next to the service they are about.
Sources
The markup and JavaScript figures are this site's own, from the audit named below, across all 40 trades, with no landscaping cut. What schema.org's types accept and what Google asks of markup, rendering, reviews and doorway pages is stated as those pages state it.
Sources: our audit of 9,483 small-business sites, with its method · schema.org, LocalBusiness and its subtypes · schema.org, Service · Google, JavaScript SEO basics · HTML Standard, images · Google, introduction to structured data · Google, local business structured data · Google, general structured data guidelines · Google, review snippet · Google Search Central, spam policies
Read on