All insights
    Technical SEO10 min read

    Marine Schema Markup: Structured Data Examples for Marinas, Charters and Sailing Schools

    Schema markup is the cheapest technical SEO win most marine websites have never taken. It does not make you rank by itself, but it tells Google exactly what a page is — a marina, a charter itinerary, an RYA course, a regatta — and that is what earns rich results, entity understanding, and inclusion in AI answers. Every example below is copy-paste JSON-LD you can adapt today.

    Yacht sailing on Manila Bay with the city skyline on the horizon
    Sailing on Manila Bay with the city skyline behind.Photo: Philippine School of Yachting — Client photo, used with permission

    What marine schema markup actually is

    Structured data is a machine-readable description of a page, written in the schema.org vocabulary and delivered as JSON-LD inside a script tag in the head. Google reads it to confirm what your page represents rather than inferring it from the copy.

    For marine businesses that matters more than average, because the words are ambiguous. "Charter" means a boat trip to a sailor and a legal document to a search engine. "School" could be a college. "Berth" could be a bunk. Schema removes the guesswork.

    • Use JSON-LD, not microdata — it is Google's stated preference and easier to maintain
    • One @graph per page, with the entities that page genuinely represents
    • Markup must describe content that is visible on the page
    • Every entity gets a stable @id so pages can reference each other

    Marina and boatyard: LocalBusiness markup

    Marinas, boatyards, chandleries and service yards are local businesses first. The single highest-value markup is a complete LocalBusiness entity with consistent name, address and phone — the same NAP you use on your Google Business Profile.

    Only publish an address, phone number or opening hours you actually operate. Inconsistent NAP data does more local-ranking damage than missing markup.

    Marina — LocalBusiness with amenities and geo

    json

    Place in the head of the marina's home page or location page. Swap the values; delete any property you cannot verify.

    {
      "@context": "https://schema.org",
      "@type": "LocalBusiness",
      "@id": "https://example-marina.com/#marina",
      "name": "Example Bay Marina",
      "description": "Full-service marina with 220 berths, fuel dock, and haul-out.",
      "url": "https://example-marina.com/",
      "telephone": "+63-2-1234-5678",
      "address": {
        "@type": "PostalAddress",
        "streetAddress": "1 Harbour Road",
        "addressLocality": "Subic Bay",
        "addressRegion": "Zambales",
        "postalCode": "2222",
        "addressCountry": "PH"
      },
      "geo": { "@type": "GeoCoordinates", "latitude": 14.7956, "longitude": 120.2742 },
      "openingHoursSpecification": [{
        "@type": "OpeningHoursSpecification",
        "dayOfWeek": ["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"],
        "opens": "07:00", "closes": "18:00"
      }],
      "amenityFeature": [
        { "@type": "LocationFeatureSpecification", "name": "Fuel dock", "value": true },
        { "@type": "LocationFeatureSpecification", "name": "Travel lift", "value": true },
        { "@type": "LocationFeatureSpecification", "name": "Shore power", "value": true }
      ]
    }
    Two keelboats racing close together under full sail with a mountainous coastline behind
    Keelboats racing bow to bow in a Philippine regatta.Photo: Sailing.ph (Sailing Circuit) — Client photo, used with permission

    Boat dealers and brokerage listings: Product and Offer

    A boat for sale is a Product with an Offer. Dealers and brokers who mark listings up correctly become eligible for price, availability and condition treatment in results — and give Google a clean signal about inventory that a photo gallery never provides.

    Keep the price in sync with the page. Structured data that contradicts visible price is a manual-action risk, not a shortcut.

    Brokerage listing — Product + Offer

    json

    One block per listing page. itemCondition uses UsedCondition for brokerage stock.

    {
      "@context": "https://schema.org",
      "@type": "Product",
      "name": "2019 Beneteau Oceanis 46.1",
      "sku": "BRK-2019-OC461",
      "brand": { "@type": "Brand", "name": "Beneteau" },
      "image": ["https://example-brokers.com/img/oceanis-461-1.jpg"],
      "description": "Owner's version, 3 cabins, full electronics refit 2024.",
      "itemCondition": "https://schema.org/UsedCondition",
      "offers": {
        "@type": "Offer",
        "price": "395000",
        "priceCurrency": "EUR",
        "availability": "https://schema.org/InStock",
        "url": "https://example-brokers.com/listings/oceanis-461",
        "seller": { "@type": "Organization", "name": "Example Yacht Brokers" }
      }
    }

    Yacht charter: Trip, TouristAttraction and bookable Offers

    Charter itineraries map to BoatTrip (a subtype of Trip), with an Offer carrying the price and a potentialAction that points at your booking flow. Day sails and sunset cruises use the same shape.

    If the price varies by season, publish a priceSpecification range rather than a single figure you will contradict in the booking engine.

    Charter itinerary — BoatTrip with offer and booking action

    json
    {
      "@context": "https://schema.org",
      "@type": "BoatTrip",
      "name": "Three-day Batangas island cruise",
      "description": "Skippered charter from Batangas to Puerto Galera and back.",
      "provider": { "@type": "Organization", "name": "Example Charters" },
      "departureBoatTerminal": { "@type": "BoatTerminal", "name": "Batangas Yacht Club" },
      "arrivalBoatTerminal": { "@type": "BoatTerminal", "name": "Batangas Yacht Club" },
      "offers": {
        "@type": "Offer",
        "priceCurrency": "USD",
        "priceSpecification": {
          "@type": "PriceSpecification",
          "minPrice": "1200",
          "maxPrice": "1850",
          "priceCurrency": "USD"
        },
        "availability": "https://schema.org/InStock",
        "url": "https://example-charters.com/book/batangas-three-day"
      },
      "potentialAction": {
        "@type": "ReserveAction",
        "target": {
          "@type": "EntryPoint",
          "urlTemplate": "https://example-charters.com/book/batangas-three-day",
          "actionPlatform": ["https://schema.org/DesktopWebPlatform","https://schema.org/MobileWebPlatform"]
        }
      }
    }
    Two crew members checking lines and safety gear on a yacht alongside a marina berth
    Pre-departure checks alongside the berth.Photo: Philippine School of Yachting — Client photo, used with permission

    Sailing schools: Course and CourseInstance

    An RYA, ASA or Australian Sailing course page should be a Course with one CourseInstance per scheduled intake. This is the markup that lets a course calendar surface dates, mode of delivery and price — and it is almost universally missing from sailing school sites.

    Add the awarding body as an accreditation or in the provider's description only when the recognition is current and verifiable.

    Beginner keelboat course — Course + CourseInstance

    json

    Repeat hasCourseInstance for each published intake; drive it from your course calendar data.

    {
      "@context": "https://schema.org",
      "@type": "Course",
      "name": "RYA Competent Crew",
      "description": "Five-day live-aboard beginner course covering seamanship and helming.",
      "provider": {
        "@type": "Organization",
        "name": "Example School of Yachting",
        "url": "https://example-school.com/"
      },
      "educationalCredentialAwarded": "RYA Competent Crew certificate",
      "hasCourseInstance": [{
        "@type": "CourseInstance",
        "courseMode": "onsite",
        "location": { "@type": "Place", "name": "Subic Bay, Philippines" },
        "startDate": "2026-09-14",
        "endDate": "2026-09-18",
        "courseWorkload": "P5D",
        "offers": {
          "@type": "Offer",
          "price": "790",
          "priceCurrency": "USD",
          "availability": "https://schema.org/InStock",
          "url": "https://example-school.com/courses/competent-crew"
        }
      }]
    }

    Regattas and club events: SportsEvent

    Race notices, regattas and club series are SportsEvent. Mark up the entry offer if entries are sold online, and use eventAttendanceMode plus eventStatus so postponements and cancellations are machine-readable.

    Only publish dates you can source from the notice of race or the organising authority. Provisional dates should be labelled as such on the page and left out of startDate until confirmed.

    Regatta — SportsEvent with entry offer

    json
    {
      "@context": "https://schema.org",
      "@type": "SportsEvent",
      "name": "Example Bay Regatta 2026",
      "sport": "Sailing",
      "startDate": "2026-11-06",
      "endDate": "2026-11-08",
      "eventStatus": "https://schema.org/EventScheduled",
      "eventAttendanceMode": "https://schema.org/OfflineEventAttendanceMode",
      "location": {
        "@type": "Place",
        "name": "Example Bay Yacht Club",
        "address": { "@type": "PostalAddress", "addressLocality": "Subic Bay", "addressCountry": "PH" }
      },
      "organizer": { "@type": "Organization", "name": "Example Bay Yacht Club" },
      "offers": {
        "@type": "Offer",
        "name": "Entry fee",
        "price": "150",
        "priceCurrency": "USD",
        "url": "https://example-club.com/regatta/entry",
        "availability": "https://schema.org/InStock",
        "validFrom": "2026-08-01"
      }
    }

    Tie the site together with @graph and @id

    Individual snippets are useful; a connected graph is better. Publish one Organization entity with a stable @id, then reference it from every page-level entity instead of repeating the details. That is how search engines build an entity picture of your business rather than a pile of unrelated pages.

    Add BreadcrumbList on every deep page and WebPage on every page — both are cheap and both improve how your URLs are displayed and understood.

    Site-wide graph pattern

    json

    The Organization block lives once, on the home page. Everything else points at its @id.

    {
      "@context": "https://schema.org",
      "@graph": [
        {
          "@type": "Organization",
          "@id": "https://example-marina.com/#org",
          "name": "Example Bay Marina",
          "url": "https://example-marina.com/",
          "sameAs": ["https://www.facebook.com/examplebaymarina"]
        },
        {
          "@type": "WebPage",
          "@id": "https://example-marina.com/berths#page",
          "url": "https://example-marina.com/berths",
          "name": "Berths and moorings",
          "isPartOf": { "@id": "https://example-marina.com/#org" }
        },
        {
          "@type": "BreadcrumbList",
          "itemListElement": [
            { "@type": "ListItem", "position": 1, "name": "Home", "item": "https://example-marina.com/" },
            { "@type": "ListItem", "position": 2, "name": "Berths", "item": "https://example-marina.com/berths" }
          ]
        }
      ]
    }

    Validate, then keep validating

    Ship nothing without running it through Google's Rich Results Test and the schema.org validator. Then set up a repeatable check, because structured data breaks silently the moment a template changes or a CMS field goes empty.

    On our own site every page's JSON-LD is generated from typed data and covered by automated tests, so a malformed graph fails the build rather than quietly disappearing from search results.

    • Google Rich Results Test — eligibility for rich treatment
    • Schema Markup Validator (validator.schema.org) — vocabulary correctness
    • Search Console → Enhancements — errors at scale, after indexing
    • Automated tests in your build for required fields and valid JSON

    The five errors we find on almost every marine site

    These are the recurring faults from technical audits of marina, charter and school sites. All five are fixable in an afternoon.

    • Markup describing content that is not visible on the page (FAQ answers hidden or absent)
    • Prices in schema that no longer match the booking engine
    • Every page repeating the home page's LocalBusiness block, so each URL claims to be the business
    • Duplicate conflicting blocks from an SEO plugin plus a theme plus a manual snippet
    • Empty fields rendered as empty strings instead of being omitted, which invalidates the object
    Takeaway

    Marine schema markup is a one-off build with compounding returns: a single Organization graph, the right entity per template (LocalBusiness, Product, BoatTrip, Course, SportsEvent), visible content behind every claim, and automated validation so it stays correct.

    FAQ

    Frequently asked questions

    What is marine schema markup?

    Marine schema markup is schema.org structured data applied to boating websites — marinas, boat dealers, charter operators, sailing schools and clubs. It is JSON-LD added to the page that tells search engines the page describes a marina, a boat for sale, a charter itinerary, a course intake or a regatta rather than leaving them to infer it from the copy.

    Does schema markup improve rankings?

    Not directly. Structured data is not a ranking factor on its own, but it makes pages eligible for rich results, improves click-through rate, and strengthens entity understanding — which in practice shows up as more clicks for the same position and better inclusion in AI-generated answers.

    Which schema types should a marina use?

    Start with Organization site-wide, LocalBusiness on the marina location page with NAP, geo and amenityFeature, WebPage plus BreadcrumbList on every page, and FAQPage where you have a visible FAQ. Add Service entities for haul-out, storage and repairs if those have their own pages.

    What schema should a yacht charter company use?

    BoatTrip (a Trip subtype) for each itinerary, with an Offer or priceSpecification and a ReserveAction pointing at your booking flow. Add Product and Offer if you also sell fixed packages, and Review or AggregateRating only where genuine, verifiable reviews are displayed on the page.

    Is JSON-LD better than microdata for marine websites?

    Yes. JSON-LD is Google's recommended format, sits in a single script tag, and can be generated from your CMS data without touching page HTML — which matters when charter prices, course dates and berth availability change constantly.

    How do I check my schema markup is working?

    Run the URL through Google's Rich Results Test and validator.schema.org, then monitor Search Console's Enhancements reports after indexing. For sites where the markup is generated from a CMS, add automated tests so an empty field or a template change fails your build instead of silently removing the markup.

    Can bad schema markup hurt my site?

    It can. Markup describing content that is not visible, prices that contradict the page, or the business's LocalBusiness block repeated on every URL can all trigger a structured-data manual action or simply cause Google to ignore your markup entirely.

    Want your structured data built and validated for you?

    Our marine technical SEO audit includes a full structured-data review — what is missing, what is invalid, and the exact JSON-LD to ship for every template on your site.

    See the marine technical SEO audit
    Next Step

    Want this run for you?

    Share your goals and we'll come back with a marine marketing plan, scope, and quote.