Home / Resources / Fix / Organization Schema for SaaS: Implement the Homepage and Logo
AI Search Intelligence

Organization Schema for SaaS: Implement the Homepage and Logo

The short answer

Describe the company separately from its software, connect the website to its publisher, and check the actual logo file referenced by the markup. A working homepage does not prove that its image exists or meets the intended requirements. This fictional example pairs a complete company graph with a runnable HTTP lab: the homepage succeeds in all three cases, while an undersized logo and a missing file fail separate asset checks.

Copy the company homepage and logo lab

Save as organization-example.mjs and run node organization-example.mjs with Node 24. No packages are needed. Run node organization-example.mjs --html > homepage.html to inspect the complete fictional HTML. The lab uses loopback HTTP and closes its server when finished.

// Fictional local HTTP lab. Node 24; no packages or external requests.
import { createServer } from 'node:http';
import assert from 'node:assert/strict';

export function homepage(origin, variant = 'ready') {
  const logo = `${origin}/logo.svg?variant=${variant}`;
  const graph = {
    '@context': 'https://schema.org',
    '@graph': [
      {
        '@type': 'Organization',
        '@id': `${origin}/#organization`,
        name: 'Cedar Quay',
        legalName: 'Cedar Quay Software LLC',
        url: `${origin}/`,
        description: 'A fictional company making bookkeeping software.',
        logo,
      },
      {
        '@type': 'WebSite',
        '@id': `${origin}/#website`,
        url: `${origin}/`,
        name: 'Cedar Quay',
        publisher: { '@id': `${origin}/#organization` },
      },
    ],
  };
  return `<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Cedar Quay — fictional company example</title>
<link rel="canonical" href="${origin}/">
<script type="application/ld+json">
${JSON.stringify(graph, null, 2)}
</script>
</head>
<body>
<main>
<img src="${logo}" alt="Cedar Quay logo">
<h1>Cedar Quay</h1>
<p>A fictional company making bookkeeping software.</p>
<p>Cedar Quay Software LLC operates this website.</p>
<p>This is a teaching example, not a real company.</p>
</main>
</body>
</html>`;
}

function logoSvg(size) {
  return `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 256 256"><rect width="256" height="256" fill="white"/><path d="M176 64H96L64 96v64l32 32h80v-32h-64l-16-16v-32l16-16h64z" fill="#17324d"/></svg>`;
}

async function runLab() {
  let origin;
  const server = createServer((request, response) => {
    const url = new URL(request.url, origin);
    const variant = url.searchParams.get('variant') || 'ready';
    if (url.pathname === '/') {
      response.writeHead(200, { 'content-type': 'text/html; charset=utf-8' });
      return response.end(homepage(origin, variant));
    }
    if (url.pathname === '/logo.svg' && variant !== 'missing') {
      response.writeHead(200, { 'content-type': 'image/svg+xml' });
      return response.end(logoSvg(variant === 'small' ? 96 : 256));
    }
    response.writeHead(404, { 'content-type': 'text/plain' });
    response.end('Not found');
  });
  await new Promise(resolve => server.listen(0, '127.0.0.1', resolve));
  origin = `http://127.0.0.1:${server.address().port}`;
  const results = [];
  try {
    for (const variant of ['ready', 'small', 'missing']) {
      const page = await fetch(`${origin}/?variant=${variant}`);
      const html = await page.text();
      // Fixed-shape fixture extraction, not a general HTML/JSON-LD parser.
      const block = html.match(/<script type="application\/ld\+json">\n([\s\S]*?)\n<\/script>/);
      const graph = JSON.parse(block[1])['@graph'];
      const company = graph.find(node => node['@type'] === 'Organization');
      const site = graph.find(node => node['@type'] === 'WebSite');
      const asset = await fetch(company.logo);
      const svg = await asset.text();
      // These fixtures use explicit integer SVG dimensions. This is not an image decoder.
      const dimensions = svg.match(/<svg[^>]* width="(\d+)" height="(\d+)"/);
      const width = dimensions ? Number(dimensions[1]) : null;
      const height = dimensions ? Number(dimensions[2]) : null;
      const result = {
        variant,
        homepageStatus: page.status,
        graphTypes: graph.map(node => node['@type']),
        publisherMatches: site.publisher['@id'] === company['@id'],
        logoStatus: asset.status,
        logoContentType: asset.headers.get('content-type'),
        width,
        height,
        logoChecksPass: asset.ok && asset.headers.get('content-type') === 'image/svg+xml'
          && width >= 112 && height >= 112,
      };
      assert.equal(result.homepageStatus, 200);
      assert.equal(result.publisherMatches, true);
      assert.equal(result.logoStatus, variant === 'missing' ? 404 : 200);
      assert.equal(result.logoChecksPass, variant === 'ready');
      results.push(result);
    }
    console.log(JSON.stringify(results, null, 2));
  } finally {
    await new Promise(resolve => server.close(resolve));
  }
}

if (process.argv.includes('--html')) {
  console.log(homepage('https://example.com'));
} else {
  await runLab();
}
Version 1.0 · Cedar Quay and its logo are fictional. Replace example.com, company facts and the test logo URLs before adapting the HTML. This fixed-fixture lab is not a production crawler or general schema validator.
Quick actions

What belongs in the company homepage graph?

Start with approved company facts and one intended publishing relationship. Cedar Quay is the common name; Cedar Quay Software LLC is the fictional legal name. The website has its own identifier and references the company's identifier through publisher. The software application is a separate entity and is deliberately absent from this company-only example.

Google recommends organization markup on the homepage or one page describing the organization, and the most specific applicable subtype. It sets no required organization properties. Our minimal teaching company uses the broad Organization type; review a real business against more specific types before implementation. A SaaS label alone does not establish a physical local-business location.

For a site-name preference, Google expects WebSite markup on the domain or subdomain homepage, with name and url. Extend an existing WebSite node where appropriate. Organization and WebSite serve different descriptive roles even when their names and URLs match. Google's chosen site name is still automatic.

How do you prepare the fields and emitter?

Record the intended homepage, company ID, website ID, field owner and template or plugin that will emit the graph. The two fragment identifiers in the copied example are stable references to different things. Reusing one identifier for both would erase the distinction the publishing relationship is meant to express.

The example repeats the company name, description and operator in visible HTML, and uses the same logo URL in the image element and JSON-LD. It omits unverified addresses, social accounts, tax identifiers and contact details. For a real sameAs value, Google's guidance calls for another page about the same organization; a founder's profile or a related product is a different entity.

Inspect existing emitters before adding this graph. If company identity is already contradictory, resolve that conflict with the identity guide. If a theme or plugin emits stale values, trace the field to that source with the mismatch guide. The copied snippet is a starting implementation, not a reason to stack competing snippets.

RecordFictional implementationRelease check
CompanyOrganization; /#organizationApproved common and legal names describe the same company.
WebsiteWebSite; /#websiteHomepage URL and site name belong to this website.
PublisherReference to /#organizationThe website's publisher resolves to the company node.
Logo/logo.svg?variant=readyReplace the fixture URL and fetch the actual published image.
EmitterOne homepage JSON-LD blockReview existing output and retain a rollback version.

What makes the logo a separate acceptance check?

Google's organization guidance requires a logo of at least 112 by 112 pixels, in a supported format, accessible for crawling and indexing. It also recommends checking its appearance on a white background. A JSON string containing an image URL does not establish any of those asset properties.

Fetch the exact referenced URL after changing the asset host, path or permissions. Inspect its final response and image bytes, then check the real dimensions and appearance. A successful homepage response is only evidence about the homepage. The copied lab makes that dependency visible by keeping the page healthy while changing the image response.

The lab serves an original SVG mark with explicit dimensions and a white canvas; SVG is a supported image format. Its checker reads those fixture attributes. It does not decode arbitrary images, inspect SVG styling, assess visual legibility or prove Google can retrieve the asset. Use an image viewer and the actual host's access checks for those production decisions.

What did the runnable logo tests show?

We ran the copied program on September 12, 2026. It serves three homepage variants on a temporary loopback port, extracts each fixed-shape graph, follows the company's logo URL and checks the actual response. Every case retains the website-to-company publisher reference. The script asserts the expected positive and negative outcomes before printing its results.

The small case serves valid SVG with 96 by 96 dimensions. The missing case returns a plain-text 404. Both retain a 200 homepage response and parseable JSON-LD. Repair the image dependency in those cases; replacing the company name or adding more organization properties does not resolve either failure.

The ready case passes this local status, MIME and dimension check. Treat that result as a completed fixture check, with production access and appearance still outstanding. The test never contacts example.com or any public website; --html prints a separate example.com version for inspection and code validation.

VariantHomepage / publisherFetched logoLocal decision
ready200 / matching company ID200; image/svg+xml; 256 × 256Pass the three local asset checks.
small200 / matching company ID200; image/svg+xml; 96 × 96Replace the undersized asset.
missing200 / matching company ID404; text/plain; no dimensionsRestore the file or correct its URL.

What did the external markup validator establish?

We submitted the complete HTML printed by --html to Schema.org's public Code snippet test on September 12. It displayed one WebSite with the linked Organization expanded under publisher, zero errors and zero warnings. The two source nodes appeared as one connected result; that display did not mean the company disappeared.

This was a pasted-code observation. We did not validate a publicly deployed Cedar Quay site or use the validator to verify its fictional logo. Keep the graph result alongside the separate HTTP lab results. The public validator and the local fixed-fixture checker perform different checks, and neither certifies the real company's facts.

Google's Rich Results Test does not support site names. Use the Schema.org validator for the markup and the documented homepage requirements for that task. No Google test verdict, selected site name, knowledge panel, indexed image or improved search outcome is claimed here.

What should the production handoff contain?

Completed fictional handoff: propose one company homepage graph with the website's publisher referencing Cedar Quay. The pasted graph passed Schema.org. The 256-pixel fixture passed local asset checks; the small and missing cases correctly failed. Replace all fictional values and test URLs. Production image access, rendering and indexing remain unverified, so this is not a completed real-site launch.

For the real release, attach the approved field map, exact proposed HTML, logo URL, asset inspection, emitter diff and rollback version. Name the page and asset owners. After deployment, capture the served homepage and referenced file again, inspect crawl restrictions on both hosts, and use available Search Console inspection for Google's page view. Retain unresolved checks in the handoff.

RankEcho's Fix Engine supports the reviewed page-change workflow. Preview a sample fix when you need a scoped implementation proposal and acceptance record. This guide does not describe native logo certification or automatic deployment. Later search and referral observations belong in a separate measurement record, with no presumed schema effect.

Frequently asked questions

Do Organization and SoftwareApplication describe the same thing?

No. This example describes the publishing company and its website. Use the software guide for the application and its offer; keep the entities distinct even when their brand names overlap.

Should I copy organization markup onto every page?

Google recommends the homepage or one organization-describing page. Review the existing implementation and applicable subtype before deciding where the company record belongs.

Does a valid logo URL mean the logo works?

No. The local example keeps parseable markup and a working homepage while the image is undersized or returns 404. Fetch and inspect the actual asset separately.

Will this choose our site name or create a knowledge panel?

No result is guaranteed. The example establishes a graph-validation observation and local asset checks; it does not establish Google's selection, indexing or display.

Sources reviewed

Material technical claims below were checked against primary provider documentation. The sources support the documented control or signal, not a guarantee of indexing, ranking, an AI impression, or a citation.

5 claim-level source records
Checked 2026-09-12 · Primary-source technical documentation review · Confidence is recorded per claim.
Claim reviewedOfficial sourceReview record
Google documents organization placement, applicable properties and logo requirements.Google: organization structured dataChecked 2026-09-12 · Primary source checked September 12, 2026 · The example's local logo checks cover HTTP response, SVG MIME type and explicit dimensions only. They do not establish production crawlability or indexability. · Confidence: High
Google uses homepage WebSite markup for site-name preferences; its Rich Results Test does not support site names.Google: site namesChecked 2026-09-12 · Primary source checked September 12, 2026 · Current documentation review. No Google site-name selection or rich-result verdict was observed. · Confidence: High
SVG is among Google's supported image formats.Google: image SEO guidanceChecked 2026-09-12 · Primary source checked September 12, 2026 · The original lab serves SVG bytes. No general image decoding or browser appearance test is claimed. · Confidence: High
The publisher property can identify an Organization or Person publishing a CreativeWork.Schema.org: publisherChecked 2026-09-12 · Primary source checked September 12, 2026 · The submitted WebSite references the separate company identifier; the public validator resolved that Organization as its publisher. · Confidence: High
Schema.org's validator accepts pasted markup and displays extracted structured data.Schema.org: validator documentationChecked 2026-09-12 · Primary source checked September 12, 2026 · One complete fictional company homepage was submitted through Code snippet mode: one WebSite with a linked Organization publisher, zero errors and zero warnings. · Confidence: High
Explore the Fix Engine →
Last updated 2026-09-12 · RankEcho · Operated by Nexus Decision Systems LLC