# Oleksii Turovskyi > Full-stack developer from Ukraine specializing in WordPress, Next.js, React, Node.js, and Fastify. Builds rapid MVPs for startups and maintains high-load systems, blending development with marketing insights to ship products that solve real business challenges. ## About - **Name:** Oleksii Turovskyi - **Role:** Full-stack developer (WordPress, Next.js, React, Node.js, Fastify) - **Location:** Ukraine (Kyiv) - **Email:** alexturik@gmail.com - **Website:** https://alexturik.com ## Core expertise - WordPress (custom themes, plugins, headless with WPGraphQL/ACF/Gutenberg, WordPress VIP) - Next.js 16 (App Router, RSC, Server Actions) and React 19 - Node.js, Fastify, REST APIs, GraphQL - TypeScript, JavaScript, PHP 8.3 - WooCommerce (plugins, payment integrations: Dintero, Nets, Klarna) - Marketing/analytics integration: GA4 (with BigQuery sync), GTM (client + server-side), Marketo, HubSpot, Klaviyo - Performance: Core Web Vitals, JSON-LD, SEO - Build/infrastructure: Vite, Docker, CI/CD, Vercel, Google Cloud ## Pages - [Oleksii Turovskyi — Full-stack Developer](https://alexturik.com): Portfolio, intro, projects, experience, contact. Markdown: https://alexturik.com/index.md - [Writing](https://alexturik.com/blog): Writing on full-stack development, AEO and Core Web Vitals. Markdown: https://alexturik.com/blog.md - [WordPress Plugins](https://alexturik.com/plugins): WordPress plugins shipped by Oleksii Turovskyi (case studies + downloads). Markdown: https://alexturik.com/plugins.md - [Chrome Extensions](https://alexturik.com/extensions): Browser extensions on the Chrome Web Store. Markdown: https://alexturik.com/extensions.md - [Tools](https://alexturik.com/tools): Free browser-only tools — nothing is uploaded, no account needed. Markdown: https://alexturik.com/tools.md - [Embedding Playground](https://alexturik.com/tools/embedding-playground): Compare up to five texts by meaning; a sentence-transformer model runs locally in the browser and returns the full similarity matrix as JSON. Markdown: https://alexturik.com/tools/embedding-playground.md - [Answer Engine Optimization](https://alexturik.com/aeo): Pillar page for the AEO/GEO cluster — the full reading order with each article summarised. Markdown: https://alexturik.com/aeo.md - [AEO & GEO Glossary](https://alexturik.com/aeo/glossary): Definitions of the AEO/GEO vocabulary — llms.txt, JSON-LD, embeddings, chunking, grounding, RAG. Markdown: https://alexturik.com/aeo/glossary.md - [Privacy Policy — alexturik AEO Checker](https://alexturik.com/aeo/privacy): Privacy policy for the AEO Checker Chrome extension (no data collected). Markdown: https://alexturik.com/aeo/privacy.md - [Profile (Markdown)](https://alexturik.com/profile.md): Full résumé in plain Markdown — preferred for AI ingestion - [CV (PDF)](https://alexturik.com/cv_Oleksii_Turobskyi.pdf): Downloadable CV - [Resume (JSON Resume schema)](https://alexturik.com/resume.json): Machine-readable résumé - [Blog RSS](https://alexturik.com/blog/feed.xml): Atom/RSS feed for posts - [Sitemap](https://alexturik.com/sitemap.xml) ## Agent tools (WebMCP) In-browser agents (Chrome 149+, WebMCP origin trial) can call structured tools exposed via `navigator.modelContext`. No tool creates, modifies, or deletes site data: the read tools change nothing at all, and the three state-changing tools only navigate the browser or start a file download (non-destructive, safe to repeat). A JSON catalog backing these tools is at [https://alexturik.com/api/mcp/catalog](https://alexturik.com/api/mcp/catalog). Read-only tools (`readOnlyHint: true`): - `list_plugins` — no input. Output: JSON `{ plugins: [{ slug, title, tagline, description, category, status, version, url, markdownUrl, downloadable }] }`. Catalog summaries of ALL WordPress plugins; for one plugin's full page call `get_plugin`. - `list_extensions` — no input. Output: JSON `{ extensions: [{ slug, title, tagline, description, category, status, version, webStoreUrl, url, markdownUrl }] }`. Catalog summaries of ALL Chrome extensions; for one extension's full page call `get_extension`. - `list_blog_posts` — no input. Output: JSON `{ posts: [{ slug, title, description, date, tags, url, markdownUrl }] }`. Catalog summaries of ALL blog posts; for one full article call `get_blog_post`. - `get_plugin` — input `{ slug }`. Output: the plugin page's full Markdown (case study + install guide + FAQ). Discover slugs with `list_plugins`. - `get_extension` — input `{ slug }`. Output: the extension page's full Markdown. Discover slugs with `list_extensions`. - `get_blog_post` — input `{ slug }`. Output: the article's full Markdown. Discover slugs with `list_blog_posts`. - `get_contact_info` — no input. Output: JSON `{ name, email, website, github, linkedin, x }`. - `get_resume` — no input. Output: résumé JSON (`name`, `email`, `telephone`, `summary`, `experience[]`, `education[]`, `skills[]`, `url`, `sameAs[]`) — the same document as [/resume.json](https://alexturik.com/resume.json). State-changing tools (browser-side effects only — never site data; non-destructive and idempotent): - `navigate_to` — input `{ path }` (internal path like `/plugins/wdpa`). Output: JSON `{ ok, path, message }`. Navigates the current tab to a known internal page; refuses unknown paths with `ok: false`. - `download_plugin` — registered only on a `/plugins/` page; no input. Output: JSON `{ ok, path, message }`. Starts the token-gated .zip download of the plugin being viewed. - `find_content` — declarative `
` tool in the site footer; input `{ q }` (name or slug). Finds a plugin, extension, or blog post and navigates the browser to its page (fallback: the /plugins index); returns no data payload. Declarative forms carry no annotations channel, so its safety contract is stated here and in its `tooldescription`. ## Writing - [Skip the AI Visibility Checker: Audit Your Site by Hand](https://alexturik.com/blog/how-to-audit-ai-visibility) ([Markdown](https://alexturik.com/blog/how-to-audit-ai-visibility.md)) — Run the same eight checks a paid AI visibility checker runs, for free: llms.txt, robots.txt, JSON-LD, and real 2026 baselines to compare your site against. - [GEO vs SEO vs AEO — What Actually Changes in Your Workflow](https://alexturik.com/blog/geo-vs-seo-vs-aeo) ([Markdown](https://alexturik.com/blog/geo-vs-seo-vs-aeo.md)) — I scanned 93 pages ranking for AEO and GEO queries to see whether the people explaining the difference follow their own advice. Only 25.8% did. - [Embeddings: How AI Search Turns Your Page Into 384 Numbers](https://alexturik.com/blog/embeddings-how-ai-search-turns-your-page-into-numbers) ([Markdown](https://alexturik.com/blog/embeddings-how-ai-search-turns-your-page-into-numbers.md)) — AI search doesn't match keywords - it compares vectors. Turn your text into an embedding, run cosine similarity live, and watch stuffing win the wrong race. - [The Temporal API: Fixing 30 Years of JavaScript Dates](https://alexturik.com/blog/the-temporal-api-fixing-javascript-dates) ([Markdown](https://alexturik.com/blog/the-temporal-api-fixing-javascript-dates.md)) — JavaScript's Date has shipped the same bugs since 1995 — mutation, zero-based months, no real time zones. Temporal fixes them, run every example live. - [How I Added llms.txt to My Next.js Blog in 15 Minutes](https://alexturik.com/blog/how-i-added-llms-txt-to-my-nextjs-blog-in-15-minutes) ([Markdown](https://alexturik.com/blog/how-i-added-llms-txt-to-my-nextjs-blog-in-15-minutes.md)) — How llms.txt works, why 52.7% of pages ranking for AEO and GEO queries now serve one, and two ways to ship it on a Next.js blog in 15 minutes. - [The 3-Word Tag That Hides Your Best Pages from AI](https://alexturik.com/blog/the-3-word-tag-that-hides-your-best-pages-from-ai) ([Markdown](https://alexturik.com/blog/the-3-word-tag-that-hides-your-best-pages-from-ai.md)) — Three words in `` can hide your best article from ChatGPT, Claude, and Perplexity — even if Google still shows it. The silent AEO killer. - [Recency and Authority — Two Fields AI Uses to Trust You](https://alexturik.com/blog/recency-and-authority-two-schema-fields-that-decide-ai-trust) ([Markdown](https://alexturik.com/blog/recency-and-authority-two-schema-fields-that-decide-ai-trust.md)) — Before quoting your article, AI runs two checks — is it fresh, and who wrote it. Both ride on machine-readable signals. Here's the canonical setup. - [How to Help AI Understand Your Content with JSON-LD](https://alexturik.com/blog/help-ai-understand-your-content-with-json-ld) ([Markdown](https://alexturik.com/blog/help-ai-understand-your-content-with-json-ld.md)) — LLMs ground answers in structured data. With schema.org markup, the model sees a typed object — author, date, headline. Here's the canonical setup. - [The Invisible Tags Shaping Your AI Citations](https://alexturik.com/blog/the-invisible-tags-shaping-your-ai-citations) ([Markdown](https://alexturik.com/blog/the-invisible-tags-shaping-your-ai-citations.md)) — title, meta description, og:image, canonical — four tags decide if ChatGPT and Perplexity render your brand on the citation card. The bundle. - [Semantic HTML — Skipping Headings Breaks AI Optimization](https://alexturik.com/blog/semantic-html-for-machines-heading-hierarchy) ([Markdown](https://alexturik.com/blog/semantic-html-for-machines-heading-hierarchy.md)) — AI crawlers parse your heading outline before anything else. Skip an H3 and you create a phantom node — here's how to keep structure clean for LLMs. - [The JavaScript Trap — Why AI Bots See Empty Pages](https://alexturik.com/blog/the-javascript-trap-why-ai-bots-see-empty-pages) ([Markdown](https://alexturik.com/blog/the-javascript-trap-why-ai-bots-see-empty-pages.md)) — AI crawlers don't run JavaScript. If your raw HTML is a hollow `
`, you're invisible to ChatGPT, Claude, and Perplexity. - [Why Your Site Doesn't Show Up in ChatGPT (or Perplexity)](https://alexturik.com/blog/why-your-site-doesnt-show-in-chatgpt-and-perplexity) ([Markdown](https://alexturik.com/blog/why-your-site-doesnt-show-in-chatgpt-and-perplexity.md)) — Three robots.txt strategies for AI crawlers, and the two configuration mistakes that quietly cut you out of ChatGPT, Claude, and Perplexity answers. ## Plugins - [A/B Testing for Gutenberg](https://alexturik.com/plugins/ab-testing-gutenberg) ([Markdown](https://alexturik.com/plugins/ab-testing-gutenberg.md)) — WordPress plugin adding an A/B Test block to Gutenberg — cookieless round-robin variants, click and dwell-time tracking, per-test analytics dashboard. - [Yoast Video SEO Booster](https://alexturik.com/plugins/yoast-video-seo-booster) ([Markdown](https://alexturik.com/plugins/yoast-video-seo-booster.md)) — Fix Search Console's 'video is not the main content of the page' error on WordPress + Yoast SEO. Generates video-sitemap.xml and a dedicated watch page per video. - [WP Deep Performance Analyzer](https://alexturik.com/plugins/wdpa) ([Markdown](https://alexturik.com/plugins/wdpa.md)) — Deep WordPress performance profiling — hook analysis, autoloaded options audit, asset graph, HTTP and AJAX monitoring, object-cache diagnostics. ## Extensions - [NotebookLM Mindmap Controls](https://alexturik.com/extensions/notebooklm-mindmap-controls) ([Markdown](https://alexturik.com/extensions/notebooklm-mindmap-controls.md)) — Chrome extension that adds keyboard shortcuts, zoom, and pan controls to NotebookLM's mindmap view — turn a passive diagram into an explorable knowledge graph. - [AEO Checker](https://alexturik.com/extensions/aeo-checker) ([Markdown](https://alexturik.com/extensions/aeo-checker.md)) — Chrome extension that audits the current page for AI-readiness — checks description and title length, robots meta, JSON-LD, llms.txt and surfaces a 0–100 AEO Score. ## Optional - [GitHub](https://github.com/turovskiy) - [LinkedIn](https://linkedin.com/in/alexturik) - [X / Twitter](https://x.com/alexturik) - [CodePen](https://codepen.io/turovskiy)