One Typed Content Source for Pages, JSON-LD and llms.txt
By Maksym Bardakh Ivko · Chief Executive Officer
In short
On bbmmtech.com, BBMM Technologies keeps company facts, products, FAQ answers and articles in a few content modules. Pages, JSON-LD, the sitemap, the feed and both llms files are all computed from them at build time. We moved to this after a hand-written llms.txt contradicted the live site, and we back it with tests that fail the build when two copies disagree.
The drift that led to the change
Until 7 October 2026 the llms.txt on bbmmtech.com was a hand-written file of 76 lines in the public folder. Its last edit was on 16 September. Three weeks later it disagreed with the site in two places.
The file said the blog was archived writing excluded from search indexes. By then the blog was live, listed in the sitemap and published in the feed. The file also described Flowo as an iPhone app. The site's product record had listed both the App Store and Google Play since 23 September.
No one had made a wrong edit. The file was a second copy of facts held elsewhere, and the first copy had moved. We deleted it and replaced it with a 115-line module that builds the text from the same data the pages render.
The modules that hold content
Content on bbmmtech.com lives in five modules.
- The site module: the company record, the four services, the product list, the commitments, the open roles, the recognition entry and the contact addresses.
- The FAQ module: four categories holding 18 question and answer pairs.
- The blog module: each article with its summary, sections, key points, questions and references.
- The legal module: eight documents, each with a slug and a title.
- The publication module: one function that returns the articles that are currently released.
The product list has a TypeScript type. A product must have a name, URL, platform, role, summary and image. Two store links are optional. The compiler rejects a product record that omits a required field, and CI runs the type check before the build.
What one record feeds
A single product record is read by four consumers. The work section of the home page renders it. A builder turns it into a SoftwareApplication block. The Organization block lists it under owns. The llms module prints it as one line with its name, platform, URL and summary.
Some structured fields are computed from the record. The operatingSystem value is computed from which store links exist. A record with both links yields iOS and Android, a record with only an App Store link yields iOS, and a record with neither yields macOS. Adding the Google Play link to Flowo's record changed the structured data and the visible page in one commit. The hand-written llms.txt was the one output that did not follow.
The FAQ array has three consumers: the definition list on the FAQ page, the FAQPage block, and llms-full.txt. An article has six: its page, a BlogPosting block, an optional FAQPage block, the RSS feed, the sitemap and llms-full.txt.
One function for URLs and one for release
Two small functions remove whole classes of disagreement. The first builds every absolute URL the site states about itself. The site is served with trailing slashes, so a path without one answers with a redirect. The function appends the slash unless the path ends in a file extension. Open Graph URLs, structured data, the feed and the llms files all call it. The old hand-written file linked to the FAQ without the slash.
The second function returns the released articles. The article route uses it to decide which pages to generate. The sitemap, the feed and both llms files use the same call. An article is therefore counted in all five outputs or in none of them.
The sitemap applies one more rule from the same data. A tag page gets an entry only when at least three released articles carry the tag.
Checks that fail the build
Generation covers the copies we can compute. Tests cover the ones we cannot. On bbmmtech.com, the six home page questions are looked up by their exact text in the FAQ array, and a missing question throws during the build. A unit test asserts that with the release gate off, every article is released.
flowoapp.com keeps a hand-written llms.txt, so its build ends with a validation script. The script collects every flowoapp.com URL found in llms.txt and in the sitemap, then checks the build output for each one.
- 1.The prerendered file for the URL exists.
- 2.The page has a non-empty title and an h1.
- 3.The page declares exactly one canonical link.
- 4.Every JSON-LD block on the page parses.
- 5.Each of the five language home pages carries six hreflang links, one per language plus x-default.
- 6.llms-full.txt contains a URL line for every sitemap page except the language home pages.
Unit tests on the same site compare prose against data. One reads the pricing catalogue and requires llms.txt to state each of the three Pro prices and the 14-day trial. Another scans four source files for seven retired prices and fails if any appears. A third requires the Organization block on flowoapp.com to carry the registry number that bbmmtech.com publishes, so the two sites describe the company identically.
What is still duplicated
The model is incomplete, and we list the gaps here because each one is a place where drift can return.
- The Organization builder on bbmmtech.com writes the legal name, address, founding date and registry number as literals. Only its list of owned products reads the site module.
- The legal module holds its own company record, separate from the one the pages use.
- The sitemap has its own date literal for static routes. It equals the reviewed-date constant today only because both were edited together.
- Two sections of llms.txt are written by hand in the llms module, the naming rules and the list of things we do not claim, because no other part of the site states them.
The flowoapp.com llms.txt remains hand-written by choice. It contains explanations of scheduler behaviour that exist nowhere in structured form, so we guard it with tests.
Key takeaways
- The hand-written llms.txt on bbmmtech.com drifted within three weeks and was replaced on 7 October 2026 by a module that builds it from the site's content data.
- One product record on bbmmtech.com feeds the home page, a SoftwareApplication block, the Organization block and llms.txt.
- The operatingSystem field in the product structured data is derived from which store links the record contains.
- A single released-articles function decides what appears in the generated pages, the sitemap, the feed and both llms files.
- The flowoapp.com build fails if a URL named in llms.txt has no prerendered page or if llms-full.txt omits a sitemap page.
- The Organization block on bbmmtech.com still hardcodes the company's legal name, address and registry number.
Frequently asked questions
- What is a structured content model for a website?
- It is an arrangement where facts are stored once as data and every output is computed from that data. On bbmmtech.com the company record, products, FAQ answers and articles live in content modules. The pages, JSON-LD, sitemap, feed and llms files read from them at build time.
- Why did a hand-written llms.txt go out of date?
- It was a second copy of facts that lived in the site's data. When Flowo gained a Google Play listing and the blog went live, the data changed and the file stayed the same. BBMM Technologies replaced the file with one generated during the build.
- How can structured data be kept in sync with the visible page?
- Both should be produced from one source. On bbmmtech.com the FAQ page and its FAQPage block read the same array, and product structured data is built from the same record the home page renders. Where a copy cannot be generated, a test compares it against the source.
- How do you test that llms.txt matches the rest of a site?
- The flowoapp.com build extracts every site URL from llms.txt and checks that a prerendered page exists for it with a title, an h1 and one canonical link. Unit tests also require llms.txt to state the prices and trial length held in the pricing catalogue.
- Is everything on bbmmtech.com generated from one source?
- No. The Organization structured data still contains hardcoded company details, and the legal documents keep a separate company record. Two sections of llms.txt are also written by hand. These are known gaps in the model.
References
About the author
Maksym Bardakh Ivko
Chief Executive Officer
Maksym leads product at BBMM Technologies. He designs Flowo’s scheduler and writes most of what ships in it.