Payments are experiencing issues due to temporary restrictions in Russia. If your payment does not go through, please submit a support request.Our support team is available 24/7 — we are always here to help with hosting and server issues.We are now accepting requests for dedicated server rental and colocation services in our data center.Reminder: we recommend enabling backups for additional data protection.A new VPS/VDS lineup with NVMe storage and improved performance is now available.Maintenance work on some servers has been completed. All services are operating normally.
mrLexndr Microdata: schema.org, og and twitter for GEO

MODULE FOR 1C-BITRIX

mrLexndr

mrLexndr Microdata: schema.org, og and twitter for GEO

The mrLexndr Microdata module is designed for automatic generation of semantic site markup in JSON-LD format according to Schema.org standards, as well as Open Graph and Twitter Cards meta tags. The tool creates valid markup graphs for Google and Yandex search engines.

5.00/5 · 1 rating

1C-Bitrix Marketplace: 5/5 · 1 rating

Technical details

Published
8 May 2026
Updated
16 September 2026
Version
2.12.0
Installed
100–499 times
Compatible editions
First Site, Start, Standard, Small Business, Business
Responsive design
Yes
Composite support
No
Compatible with Sites24
No
Developer
mrLexndr

What this solution does

The mrLexndr Microdata module is designed for automatic generation of semantic site markup in JSON-LD format according to Schema.org standards, as well as Open Graph and Twitter Cards meta tags.

The tool creates valid markup graphs for Google and Yandex search engines. Supported Schema.org entity types include Organization and LocalBusiness, Product and Offer, Article, NewsArticle, BlogPosting, BreadcrumbList, FAQPage, ImageObject, and Person.

The module provides automatic generation of social media meta tags, including og:title, og:image, og:type, and other Open Graph parameters, as well as Twitter Cards. Organization data, such as name, logo, contacts, addresses, and operating hours, is managed via the administrative panel.

Flexible output is implemented: code can be automatically placed in the head section or manually inserted into component templates.

Technical requirements: PHP version 8.2 or higher, platform 1C-Bitrix Site Management in any edition.

General iT can handle the implementation of “mrLexndr Microdata: schema.org, og and twitter for GEO”, from installation to configuration and compatibility checks.

UPDATE HISTORY

What’s new

5 releases
2.12.0 (15.09.2026)Latest update

What changed since version 2.11.1.

What's new

Who verified the material. The page now has the reviewedBy and lastReviewed properties: who verified the content for accuracy and when. Content on complex topics is often written by an editor or marketer, while a subject-matter expert is responsible for the facts. Without markup, the page appears to be written by a non-expert author, even though it has been verified.

A reviewer can be either a person or an organization — an editorial office, a laboratory, or an expert council.

A specialist with a permanent identifier is included in the markup as a link, not a copy: all materials verified by them are linked together into a single entity.

How it looks in code

The properties are set on the page object returned by Schema::setMainEntity():

->setReviewedBy($reviewer) — accepts the same arguments as setAuthor(): a Person object, an array of fields, a name as a string, or a link by identifier. The second argument specifies the type if an organization performed the check.

->setLastReviewed($date) — the date is parsed the same way as the publication date.

Both fields are optional, and an empty value is allowed: an empty infoblock property simply will not appear in the markup, so there is no need to check it before calling. An already set value is not overwritten by an empty call.

Where exactly these properties live

On the page, not on the article. According to schema.org, reviewedBy and lastReviewed are declared for the WebPage type, and Article and WebPage are not parent and child but siblings: they do not inherit each other's properties. If set on an article, these fields would be unknown, and the Google validator would issue warnings for them.

What was fixed

The method for setting the verification date with an empty value created an empty field. It did not appear in the markup, but the entity containing it was no longer considered empty and could end up in the graph as a meaningless node. The method has existed since version 2.2.0, was not documented in the manual, and was not covered by tests — now it is documented and covered.

What to do after updating

If the site contains materials verified by a subject-matter expert, create an information block property with a link to the expert's card and call setReviewedBy() in the detailed page template. These properties are meaningless on list pages: they describe the page as a whole, not an individual item in the list.

Open any site page with the parameter ?microdata_debug=Y as an administrator and verify that the reviewer appears as a separate node in the graph.

The reviewedBy rich result is not provided by either Google or Yandex — it is a signal for the knowledge graph and for assessing the expertise of the material.

The full list of changes is in the CHANGELOG.md file inside the module. The manual is in docs/MANUAL.md.

2.11.1 (15.09.2026)

What changed after version 2.10.0.

What's new

Organization contact methods. A new "Contacts" tab in the module settings. A contact points table: each point has its own purpose, phone, email, link, and working hours. The structured list of contacts, contactPoint, is added to the markup in addition to the standard phone and email fields. Rows are added and removed via buttons; the language is automatically set to the one configured for the current site.

The organization's phone and email have moved to this same tab from the "Organization" tab. The setting keys and output remain unchanged: this is a tab relocation to keep all contact-related items together. Repeating the same number in the table is acceptable; these are different schema.org properties, not duplicates.

The site switcher in settings is now the second row of tabs.

What will change in the markup

No need to resave settings.

Days with identical working hours are now grouped into a single OpeningHoursSpecification node. Previously, a node was output for each day: a work week with Saturday off produced six nearly identical nodes; now it produces two. According to schema.org, dayOfWeek is a set, not a range, so "Mon, Wed, Fri" is structured the same way as "Mon–Fri". Both forms are valid; the change favors conciseness.

The site catalog is now included in the @id of the organization, website, and author. This applies only to cases where multiple sites share the same domain but differ by catalog: /, /en/, /cn/. Previously, all versions received the same identifier, even though their names, addresses, and contacts differed, meaning one identifier described several different entities. Now, the English version has a distinct identifier.

If there is only one site or language versions reside on different domains, nothing changes: the catalog is /, and the markup remains identical down to the byte.

What was fixed

An error message in the settings is now visible. Previously, the form reported an incorrect time format and immediately redirected to itself, so no one could see the message, and the administrator believed everything was saved. Now, when an error occurs, there is no redirect, and the entered data remains in the form, making it easy to correct.

The setBrand('#organization') idiom continues to target the organization node on sites in subfolders: the anchor is constructed based on the site catalog.

For developers

If you do not access the module classes from your code, this section does not concern you.

Organization::addContactPoint() accepts the phone as optional: a contact point can be just a link to a messenger. Previous calls work as before.

New methods have been added: Schema::getSiteDir() for the current site directory, and Schema::anchorId() for the node identifier belonging to the entire site.

Two new service classes: Service\ContactPoints (parsing and displaying contact methods) and Service\OpeningHours (schedule in schema.org format). Both are closed for inheritance, as are all other service classes of the module.

The list of contact methods is stored in a single contact_points setting as a JSON string; it should be read via ContactPoints::stored().

The rest of the public API has not changed.

What to do after updating

Fill in the 'Contacts' tab if you need a contactPoint in the markup.

Open any site page with the parameter ?microdata_debug=Y as an administrator: the panel will show the graph state and the base URL along with the site directory.

If language versions are hosted in subfolders of a single domain, run each version's page through the Google Rich Results Test.

The full list of changes is in the CHANGELOG.md file inside the module. The manual is in docs/MANUAL.md.

2.10.0 (02.09.2026)

Attention: the module requires PHP 8.2 or higher.

Support for PHP 7.4 and 8.0–8.1 has been discontinued. Before updating, check the PHP version on the site: Settings → Tools → System Check. On an older version, the module will be disabled, and the markup will disappear from the pages, while an event log entry with the reason will appear.

This is an incremental update: it includes versions 2.8.0, 2.9.0, and 2.10.0.

What's New

The News (NewsArticle) type now has its own properties. The Schema::newsArticle() factory now supports the article's dateline (preparation date and time), subtitle, and print edition details.

Markup for subscription-based content. A single call to setPaywalledSection('.paywall') marks the restricted section as required by Google documentation: without this, paid content appears to search robots as content cloaking.

The News AutoMapper now accepts the article type as an argument; for a news section, you can explicitly specify NewsArticle.

What Will Change in Site Markup

All changes improve validity. No need to resave settings.

Product availability is now derived from stock levels and catalog settings, not always marked as InStock. Out-of-stock products are no longer marked as available.

A node already rendered in the graph, when nested within other nodes, is now inserted as an @id link. Previously, a product was rendered twice—once as a separate node and once as a full copy within the page.

On error pages (404 and any 4xx/5xx codes), markup is not rendered.

og:url is no longer rendered as a relative address.

The isPartOf property has been removed from breadcrumbs; Google was issuing warnings for it.

Ratings outside the declared scale are no longer rendered at all; Google was discarding such reviews entirely.

Sections or products named "0" no longer render with an empty name.

What Was Fixed

Markup no longer disappears entirely. A single invalid byte in one value—for example, a description in windows-1251 from a 1C export—used to nullify the markup for the entire page, leaving no trace in either the HTML or the event log. Now, an invalid value is contained within its own node, not the entire page.

The built-in validator began working in the main scenario. It checked only the top level of the graph, while the typical call places the product inside the page: a product without price and photo yielded zero warnings, and the panel displayed a green "all in place".

Values from infoblock properties no longer corrupt the markup: an array of a multiple property does not turn into the word "Array", and an empty property does not crash the page.

Breadcrumbs: the last item in the chain (the current page) is no longer lost.

Discounted price, selected price type, and currency are retrieved correctly from the catalog.

The section admin panel styling files are now applied on update as well as on installation: previously, after an update, the admin panel received a 404 for the section style.

The module menu item is visible only to users who have permission for the module.

Output security: FAQ and review answer text is assembled using a whitelist of tags, links are validated by scheme, and JSON-LD is encoded so that one cannot escape from the block.

Compatibility for developers

If you have not extended the module classes in your code, this section does not concern you.

All entity setters now return static instead of self. A child class that declared : self on an overridden setter will no longer load.

Nine service classes (Schema, Normalizer, Validator, JsonBuilder, AutoMapper, PageHandler, Debug, ModuleOptions, Assets) have become final with a closed constructor: they can no longer be inherited. The SchemaType type dictionary is intentionally left open.

The public API remains otherwise unchanged: methods that existed in version 2.7.0 work with the same signatures. Values from the template — strings from infoblock properties, numbers, empty values — are accepted as before.

What to do after updating

Open any website page with the parameter ?microdata_debug=Y as an administrator: the panel will show the graph state and indicate which required fields are missing.

Visit the module settings at least once — this triggers the registration of handlers for sites updated by copying files.

Run one product page and one news page through the Google Rich Results Test.

The full list of changes is in the CHANGELOG.md file inside the module. The guide is in docs/MANUAL.md.

2.7.0 (17.08.2026)

Important when updating from 2.2.x

The update does not require re-saving settings and does not break the public API: all previously existing methods work with the same signatures. However, the markup output will change—all changes are aimed at improving validity:

The inLanguage field will appear for WebSite, WebPage, and articles—Previously, the language was not output at all

The last item—the current page—will be added to breadcrumbs—Previously, it was silently lost

The @id of a product and an article will receive an anchor #product / #article—Previously, the @id of a product matched the page URL

INN will move from vatID to taxID, OGRN to identifier—According to schema.org, taxID is indeed INN

publisher for WebSite will disappear if the organization name is not filled in—Previously, the link pointed to a non-existent node

og:locale will disappear for languages where the region is unknown—Previously, an invalid value such as sv_SV was output

A product without a numeric price will remain without an offers block — Previously, text was used instead of a number in the markup

What to do after updating:

Open any page with ?microdata_debug=Y as an administrator — a new panel will display the graph status and indicate what is missing.

Check the "Base URL" block in the panel. If the site is behind a reverse proxy and the markup uses the HTTP protocol, set base_scheme = https in the settings.

Open the module settings at least once: this triggers the settings migration and registers the button in the admin panel for sites updated by copying files.

Run one product page and one news page through the Google Rich Results Test.

If the site is behind a reverse proxy and the markup uses the HTTP protocol, enable the "Site behind a reverse proxy" option or set base_scheme = https.

If the logo was in SVG format, replace it with PNG or WebP.

2.7.0

Security audit issues from the Marketplace resolved.

Markup can no longer close the script tag. JSON-LD is encoded with flags JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT: the less-than and greater-than symbols become \u003C and \u003E. Previously, a value containing the script closing tag from an information block property, review, or 1C export would close the tag, causing the browser to execute the remainder of the line as JavaScript on a public page. For search engine robots, JSON remains valid, and URLs remain readable.

The insertion point is separately safeguarded: GraphRegistry::render() additionally replaces the script closing tag sequence with a backslash-escaped version.

FAQ answers are cleaned selectively. The new Normalizer::safeHtml() preserves markup allowed by Google for acceptedAnswer.text (headings, lists, links, emphasis) and removes script tags, iframe tags, form tags, svg tags, event attributes starting with on, and javascript: / vbscript: / data: schemes. The question is now always stripped of tags.

Review body and brand name are normalized: Review::setBody() and HasBrand::setBrand() run text through Normalizer::text(), as setName() and setHeadline() have long done.

The Host header is no longer accepted without a whitelist. Previously, with empty settings, it was used as-is, and a request with a foreign Host could poison the page cache with markup from a foreign domain. Now the host is accepted only if it matches a trusted source; SERVER_NAME from the web server configuration has been added to this list so that typical sites do not lose markup.

Proxy headers are accepted only via explicit configuration. X-Forwarded-Proto and X-Forwarded-Ssl are sent by the client, and without a proxy, anyone can forge them, forcing the HTTP protocol into canonical links. A new option "Site behind reverse proxy" has been added, disabled by default.

SVG is excluded from logo formats. Such a file executes an embedded script when opened via a direct link from the /upload/ directory. Google already requires a raster image for Organization.logo.

The debug panel warns if the base URL is not defined and markup is therefore not output.

2.6.2

Pre-release audit. Errors fixed, some of which existed since early versions.

Incorrect UTF-8 in infoblock data no longer causes text loss. Previously, string cleaning returned an empty value and logged a PHP deprecation: the product name and description disappeared entirely from the markup. Corrupted bytes are typical for 1C exports and imports.

The price is checked for numeric format. A non-numeric value no longer enters offers.price; such a product is displayed without the offers block. Formatted strings like 1 990,00 are parsed into numbers. Standard numeric prices remain unchanged.

A dangling link has been removed: WebSite.publisher pointed to the organization even when the organization itself was not added to the graph (name not filled).

The debug panel no longer writes to the event log. Previously, each opening of the panel duplicated validator warnings in b_event_log.

An author identifier collision has been fixed: an author named "123" received the same @id as a user with ID 123.

The author identifier no longer depends on the presence of the mbstring extension on the server.

An unrecognized author (e.g., ID of a non-existent user) no longer generates an empty Person node in the markup.

The parameter ?microdata_debug passed as an array no longer triggers a PHP warning.

2.6.1

Multilingual support.

The inLanguage field no longer appends the region automatically. Previously, a fallback option produced invalid tags for many languages: sv-SV instead of sv-SE, cs-CS instead of cs-CZ, da-DA instead of da-DK. Per BCP 47, a bare de is a valid tag, while a guessed region would be incorrect for an Austrian or Swiss site.

A new "Content Language" option (language_tag) allows explicit tag setting: ru-RU, en-GB, de-AT, zh-Hans-CN. It is stored separately for each site, as required for a multilingual portal.

Language tag normalization: pt_br → pt-BR, EN-gb → en-GB, support for scripts and macro-regions (zh-Hans-CN, es-419).

Bitrix language identifiers that are actually country codes are translated correctly: ua → uk-UA, by → be-BY, kz → kk-KZ, br → pt-BR, la → es-419.

The og:locale logic has been separated: the region is mandatory per the Open Graph specification, so it is inserted from a table of 50 languages. If the language is unknown, the tag is not output at all, which is better than an invalid value.

2.6.0

Entity linking, authors, classification, diagnostics.

Organization linking. The 'Profiles and directories (sameAs)' field has been supplemented with a new 'Company topics' (knowsAbout) field. This allows linking the site to a Wikidata entry and a Wikipedia article so that search engines understand exactly which company is being discussed. Step-by-step instructions are in the manual.

Author as a linked entity. The new Schema::author() method creates an author as a separate graph node with a permanent @id and registers it; articles reference it by ID rather than copying data on every page. It accepts a Bitrix user ID (which retrieves full name, photo, and position), an array of fields, or a name. Person::setWorksFor() and Person::setKnowsAbout() have been added.

Classification fields for articles: setSection(), setKeywords(), setWordCount(), setWordCountFromText(), setTimeRequired(), setArticleBody(). These are automatically filled from $arResult: word count from DETAIL_TEXT, section from the category, and keywords from TAGS.

The 'Warnings' tab in the module settings: the last 50 validator records from the event log with date, text, and page address.

New event OnBeforeMicrodataBuild — triggered before Open Graph generation, so a handler can replace the entity to reflect changes in meta tags as well.

Removing entities from the graph: GraphRegistry::remove() by @id or by object, and removeByType(). The documentation previously promised this capability, but the API did not provide it.

Automatic inLanguage for WebSite, WebPage, and articles — taken from the site language.

The 'Microdata' button in the admin panel on the public part: opens the current page with a debug panel.

2.5.2

Access to the debug panel has been restricted to administrators. Previously, rights to the module via GetGroupRight were also considered, and the default level for a module with unconfigured rights depends on the version and portal settings.

The page with the open panel is served with the Cache-Control: no-store header to prevent it from being cached and served to visitors.

2.5.1

The parsing of infoblock properties has been fixed. List properties were read from VALUE instead of VALUE_ENUM: if a brand is formatted as a list, the numeric identifier was included in the markup instead of the name. HTML properties were flattened into a string like 'Text, HTML' — the word HTML appeared directly in the markup.

Multiple properties and nested HTML values are now supported.

2.5.0

Debug panel.

The parameter ?microdata_debug=Y on a public page for an administrator displays: the composition of the graph with types and @id, a list of missing required fields, the parsing of the base URL definition (scheme, host, trusted hosts), values of main settings, the ready JSON-LD, and links to Google and Yandex validators.

The panel works even when the module is disabled, when the graph is empty, and in manual output mode — that is, precisely when diagnostics are most needed.

It does not load external styles or scripts, does not appear in REST responses, and silently disables itself on any internal error.

The validator has been updated to return findings as structured data, not just write to the log.

2.4.0

Eight new Schema.org types.

VideoObject — Video snippet, Video tab, video chapters

Recipe — Recipe card: time, calories, rating

JobPosting — Google Jobs vacancy block

Course — Course card

QAPage — Q&A block

SoftwareApplication — App rating and price

Service — Service pages

HowTo — Step-by-step instructions

General duration parsing: methods accept seconds, the string '01:30:00', or a ready ISO 8601 format.

Open Graph strategy for video: og:type = video.other, player tags, duration in seconds.

The validator checks required fields for all new types.

Constants VideoObject and Service were present in the type dictionary from early versions, but no classes existed for them.

2.3.0

Logic fixes and cleanup.

Breadcrumbs no longer lose the last item. Bitrix returns the current page with an empty link, which was silently discarded, causing the markup chain to always be shorter than the actual one.

Re-calling setMainEntity() no longer overwrites the page. Previously, a second entity (e.g., from another component) would erase the first one along with its data.

The OnAfterMicrodataBuild event now works in manual mode. Previously, in this mode, handlers triggered after the JSON output, rendering them useless.

Property mapping has been fixed: INN is mapped to taxID (which is the correct schema.org term for INN), and OGRN is mapped to identifier via PropertyValue. Setting keys are preserved.

The @id for products and articles now includes anchors #product and #article: previously, the product identifier matched the page address.

og:locale for languages other than Russian no longer outputs invalid bare language codes.

Exception masks are now checked against paths without the query string: the mask /search/ now excludes /search/?q=....

Short PHP opening tags short PHP opening tag have been removed from the settings form, so it no longer depends on the short_open_tag directive.

Validator texts have been moved to language files.

An unnecessary layer of file caching for the schedule has been removed (data is already cached by the core, and a daily TTL could return outdated schedules).

Tests without external dependencies have been added: php tests/run.php.

2.2.2

Critical fixes.

Lists in JSON no longer convert to objects. When clearing empty values in arrays, gaps in indices remained, causing json_encode to output {"0":...,"2":...} instead of [...]. Such values for sameAs, image, and itemListElement are rejected by Schema.org validators.

Correct protocol detection behind a reverse proxy. Behind nginx, Cloudflare, or a load balancer, the entire graph was previously sent as HTTP protocol even when canonical. An option "Protocol in absolute links" (base_scheme) has been added, along with support for X-Forwarded-Proto and X-Forwarded-Ssl headers.

Protection against Host header spoofing. The request host is included in the markup only if it matches a trusted source (org_url, the site's server_name, or SITE_SERVER_NAME). Without this check, a request with a foreign Host could poison the page cache with markup containing a foreign domain.

The settings migration during updates has been fixed. Bitrix does not call CModule::DoUpdate(), so transferring settings to per-site records was not performed. An install/updater.php template has been added, and the process is now idempotent when the settings form is opened.

Compatibility with PHP 7.4 has been restored. One construct required PHP 8.0: on PHP 7.4 the module installed but crashed on the first request.

The base URL is now calculated once per request instead of being recalculated on every access.

2.2.1 (08.05.2026)

- Documentation update

- New module name

USER EXPERIENCE

Solution reviews

How does this solution work in a real project? Share your experience and help others choose.

Be the first to share your experience

There are no reviews of this solution on git.ru yet. Tell us what worked well and what could be improved.

Verified purchaseAdd a key if you wish. A verified review gets a badge, priority placement and more rating weight.

Open to every clientJust sign in to your account. A key is optional; all reviews are moderated.

YOUR EXPERIENCE MATTERS

Your review

YOUR PROJECT INFRASTRUCTURE

A home for your website

BEFORE YOU ORDER

Let’s go through the details.

Is installation free?
The solution itself is free. Installation, configuration and customisation services are agreed separately. A compatible platform and an appropriate platform licence are required.
How do I check compatibility?
Compare the supported editions and solution version in the technical details with your project. Before installing on a live website, we recommend making a backup and checking the solution in a test environment.
Can you help with implementation?
We can help install the module, check its settings and verify how it works in your project. Compatibility with other customisations and the scope of work are assessed before we begin.

GENERAL iT

Let’s discuss your project

Получатель: ООО «Дженерал Ай Ти Рус»

1C-BITRIX

Install solution

Enter a domain with or without https://. The installer will open in your website control panel in a new tab.

Solution screenshots

Solution screenshot