Developments

Tatak Schema: A Free JSON-LD Builder and Checker for Philippine Small Businesses

Efraim Ray Efraim Ray 0 Comments
Developer Tool Showcase

Structured data is the hidden JSON-LD that tells search engines "this page is a restaurant, here is the address, here are the hours." Most small-business sites in the Philippines either skip it or paste markup with local phone numbers, prices like "₱1,499" and swapped map pins, so search engines quietly ignore it. I built Tatak Schema, a free browser tool that writes this markup for you and checks the markup you already have.

Tatak is Filipino for stamp or brand mark. As you type, the tool stamps your markup READY or FIX. It covers LocalBusiness, Event, FAQPage and Product, gives plain-language fixes with Philippine-specific hints, and runs entirely in the browser with no sign-up and no build step.

Type Developer Tool
Stack Vanilla JS · No backend
Frontend HTML + CSS tokens
Version v1.0.0
License Free · MIT
Tatak Schema JSON-LD builder stamping READY on structured data for a Philippine carinderia

Try It: Break the Markup

This is a trimmed version of the tool's Local business checker. Load the broken sari-sari store sample, or type a phone number like 0917 123 4567, and watch the stamp, the fixes and the JSON-LD change.

efraimray.github.io/tatak-schema/
Tatak Schema · Local business
—
    
              

    Build Footprint & Quality Checks

    The whole tool is three JavaScript files and one stylesheet. These are the measured numbers from the v1.0.0 build:

    16.2
    JavaScript
    KB gzipped (3 files)
    4.2
    CSS
    KB gzipped
    15
    Unit Tests
    15/15 passing (Node)
    0
    External Scripts
    no framework, no CDN JS

    Technology Stack & Architecture Layers

    Languages

    JavaScript · CSS · HTML

    JavaScript 75%, CSS 15%, HTML 9% and JSON 1% by line count. No TypeScript, no npm packages, nothing to compile.

    Logic Layer

    Vanilla JS UMD Core

    schema-core.js holds the field definitions, builders, validator and parser. The same file runs in the browser and in Node tests.

    Interface

    CSS Custom Properties

    Colour tokens with light and dark mode, CSS Grid layout that stacks at phone width, and an accessible tab pattern.

    Standard

    Schema.org JSON-LD

    LocalBusiness (15 sub-types), Event with offline, online or mixed attendance, FAQPage and Product with PHP offers.

    Key Architectural Decisions

    Pillar 01

    Pure Logic, Thin UI

    The core never touches the page. It takes plain data in and returns objects, issues and preview data, which makes every rule easy to test.

    Pillar 02

    Data-Driven Forms

    Every form is generated from one FIELDS list. Adding a field such as "Delivery area" is one line in the list and one in the builder.

    Pillar 03

    Safe Output

    Every < in the JSON becomes <, so a value like </script> can't break the page. All form values are escaped before rendering.

    Pillar 04

    Philippine-Aware Checks

    It suggests +63 phone formats, flags 5-digit ZIP codes, map pins outside the Philippines, swapped coordinates and prices written as "₱1,499".

    The Checker, Safe Output & Usage

    Here are three real pieces of the project: the Philippine-specific checks inside the validator, the function that makes the output safe to paste, and how you use the result.

    // src/js/schema-core.js — validate(), LocalBusiness branch (excerpt)
        if (cc === 'PH' && addr.postalCode && !/^\d{4}$/.test(str(addr.postalCode))) add('warn', 'address.postalCode', 'Philippine ZIP codes have 4 digits.');
      }
      if (obj.telephone) {
        if (!phoneOk(obj.telephone)) {
          var hint = phPhoneHint(obj.telephone);
          add('warn', 'telephone', 'Use international format' + (hint ? ', e.g. "' + hint + '"' : ' starting with +63') + '.');
        }
      } else rec('telephone', 'A phone number', 'shown on maps and call buttons');
      rec('url', 'Website URL');
      rec('image', 'A photo or logo');
      rec('openingHoursSpecification', 'Opening hours', 'lets results show "Open" or "Closed"');
      rec('priceRange', 'Price range');
      if (obj.priceRange && str(obj.priceRange).length > 100) add('warn', 'priceRange', 'Keep price range under 100 characters.');
      if (obj.geo) {
        var lat = Number(obj.geo.latitude), lng = Number(obj.geo.longitude);
        if (!isFinite(lat) || lat < -90 || lat > 90) {
          var swapped = isFinite(lng) && Math.abs(lng) <= 90 && Math.abs(lat) <= 180;
          add('error', 'geo.latitude', 'Latitude must be a number between -90 and 90.' + (swapped ? ' It looks like latitude and longitude are swapped.' : ''));
        }
        else if (!isFinite(lng) || lng < -180 || lng > 180) add('error', 'geo.longitude', 'Longitude must be a number between -180 and 180.');
        else if (addr && str(addr.addressCountry) === 'PH' && (lat < 4.2 || lat > 21.5 || lng < 116 || lng > 127.1)) {
          add('warn', 'geo', 'The map pin is outside the Philippines. Latitude and longitude may be swapped.');
        }
      } else rec('geo', 'A map pin (latitude and longitude)');
    // src/js/schema-core.js — safe output
    /** JSON safe to place inside <script>: "<" is escaped so "</script>" can't break out. */
    function toJson(obj, minify) {
      return JSON.stringify(obj, null, minify ? 0 : 2).replace(/</g, '\\u003c');
    }
    
    function toScriptTag(obj, minify) {
      return '<script type="application/ld+json">\n' + toJson(obj, minify) + '\n</script>';
    }
    
    // Philippine phone hint used by the validator
    function phPhoneHint(s) {
      var d = str(s).replace(/[\s().-]/g, '');
      if (/^09\d{9}$/.test(d)) return '+63 ' + d.slice(1, 4) + ' ' + d.slice(4, 7) + ' ' + d.slice(7);
      if (/^0\d{7,10}$/.test(d)) return '+63 ' + d.slice(1);
      return '';
    }
    <!-- 1. Copy the script tag from Tatak Schema -->
    <script type="application/ld+json">
    {
      "@context": "https://schema.org",
      "@type": "Restaurant",
      "name": "Kainan sa Poblacion",
      "telephone": "+63 917 555 0142",
      "address": { "@type": "PostalAddress", "addressLocality": "Valencia City", "postalCode": "8709", "addressCountry": "PH" }
    }
    </script>
    
    <!-- 2. Paste it:
         WordPress → Custom HTML block (or your SEO plugin's schema field)
         Blogger   → post HTML view, at the top
         Any site  → inside <head> or <body> -->
    
    # 3. Run the project's tests (Node 14+)
    node tests/core.test.js   # 15/15 tests passed

    Development Roadmap & Milestones

    Version 1.0.0 is released. The next milestones come straight from the project's roadmap:

    1

    v1.0.0: Builder & Checker (Released)

    Four schema types, 40+ plain-language checks, paste checker with @graph support, search preview, copy, minify and autosave.

    2

    Next: Organization, WebSite & Breadcrumbs

    Site-wide markup for the home page, plus combining several items into one @graph block.

    3

    Planned: Edit Pasted Markup in the Form

    Paste a client's existing markup, click "Edit in form", fix the flagged fields, and copy the corrected version.

    4

    Planned: WordPress Plugin Wrapper

    A meta box that stores the markup per page and prints it in the head, with Filipino interface labels.

    User Interface & Feature Showcase

    READYSCORE 100
    Kainan sa Poblacion
    Restaurant · ready to paste into your page
    0 errors0 suggestionsvalid
    Builder

    Stamped READY as You Type

    Fill the form or load a preset. The stamp and score update on every keystroke.

    FIX · 2 errors · pasted Product markup
    Price must be a plain number like 250 or 1499.50, without ₱ or commas.
    "banigweavers.example/queen" is not a full URL. Start it with https://
    A product image is recommended.
    Checker

    Paste Any Page's Markup

    Reads every ld+json block and @graph item, with fixes in plain language.

    mabuhaylearning.example › admissions
    Enrollment FAQ · School Year 2027–2028
    When is enrollment for SY 2027–2028?⌄
    What documents do I need for Grade 7?⌄
    Can I enroll online?⌄
    Preview

    See the Result Before You Publish

    An approximate search card with facts, prices, dates and FAQ drop-downs.

    Project Links, Code & Documentation

    Open the Live Tool

    Use it free in your browser. Nothing is uploaded; your drafts stay in your own browser.

    Launch Tatak Schema

    GitHub Repository

    Browse the source, run the tests, open an issue or suggest a feature. Free and open source under the MIT license.

    View on GitHub

    How It Was Built

    The build log lists the languages used and every step, test and fix, in plain language.

    Read the Build Log
    Engineering Takeaway

    Invisible Markup, Visible Results

    Structured data is one of the cheapest local-SEO wins, but only when it is correct. Tatak Schema writes it, checks it in plain language, and catches the mistakes that are common on Philippine sites. Want me to audit and fix the structured data on your business, school or co-op website?

    Frequently Asked Questions

    Is Tatak Schema free?

    Yes. Tatak Schema is free and open source under the MIT license. It runs in your browser with no sign-up and no install.

    Does it work with Blogger and WordPress?

    Yes. Click Copy script tag, then paste it into your Blogger post in HTML view, or into a Custom HTML block or your SEO plugin's custom schema field in WordPress. It also works on any other website.

    Will structured data give my site rich results?

    Valid markup makes a page eligible, but search engines decide what to show. Google stopped showing FAQ rich results for all sites in 2026, but LocalBusiness, Event and Product markup still help search engines and AI tools understand your page.

    Is my business information uploaded anywhere?

    No. Everything runs in your browser. Drafts are saved only in your own browser's storage, and nothing is sent to a server.

    Do I need to know how to code?

    No. Fill in the form or load a preset, fix anything the checker flags, and click Copy script tag. The plain-language checks tell you exactly what to change.

    Can you set this up for my business website?

    Yes. I can audit the structured data on your business, school or cooperative website, fix the errors, and add the correct markup for you. Contact me here.

    The businesses, school, cooperative and brand in the demo and screenshots are fictional. Search engines decide whether to show rich results; valid markup makes a page eligible, not guaranteed.

    Efraim Ray
    Written by

    Efraim Ray

    Software Developer and AI Specialist. BS Information Technology graduate. I pride myself on being conscientious, attentive to detail, and always open to learning — because the best solutions come from listening, taking notes, and exploring what's next.

    Comments