From craft-workspace-webconsulting-skills
Updates a TYPO3 v12/v13 site to v14.3 LTS inside DDEV with visual regression testing, accessibility checks, extension migration, and Lighthouse optimization.
How this skill is triggered — by the user, by Claude, or both
Slash command
/craft-workspace-webconsulting-skills:typo3-14-updateThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> Source: https://github.com/dirnbauer/webconsulting-skills
Update one extension, sitepackage, or full project from TYPO3 v12/v13 to supported TYPO3 14.3 LTS. The deliverable is the updated installation running in the local DDEV project — installable, migrated, wizard-complete, tested, documented, and rendering identically to its pre-update baseline. Produce v14-only code; do not retain v12/v13 compatibility branches or shims.
An old TYPO3 project arrives; a modern v14 site leaves. Four properties define "done", each proven by evidence rather than asserted — when a phase cannot produce its evidence, the update is not finished:
| Goal | Proven by |
|---|---|
| Fast | Lighthouse over a sampled sitemap set, optimized in a fix-and-re-measure loop (Phase 9) |
| Correct | The visual regression main loop — identical rendering before and after — plus upgrade wizards, tests, static analysis, and the backend module sweep (Phases 2, 8, 9) |
| Accessible | An axe-core-driven WCAG 2.2 AA loop run to green before the baselines and re-verified after the update (Phases 2, 8) |
| Easy to use | Visual Editor inline editing and a migrated CKEditor RTE with language and abbreviation support and live-matching styles (Phase 7) |
Every phase serves one of these four; when a decision is ambiguous, choose the option that best preserves them.
ddev composer, the TYPO3 CLI through ddev typo3 (or ddev exec vendor/bin/typo3), tests and tools through ddev exec, and browser verification against the DDEV URL.ddev snapshot before every schema change, upgrade wizard run, or data migration so each local step is reversible; keep an exported dump of the pre-update state. Ask before destructive database changes, bulk deletion, feature removal, or discarding user changes.An update must not change what visitors see: the same content on the same database renders identically by definition. The whole migration therefore runs inside one visual regression loop — baseline the synced site before touching code, update, re-shoot the same pages, and repair until the output matches:
scripts/run-tests.cjs provides the actions get-urls (main and per-language sitemap discovery combined with golden-path URLs, random sampling, 100-URL cap), take-screenshots (desktop, tablet, and phone viewports), compare-screenshots (odiff with pixelmatch fallback and a small minor-diff tolerance), smoke-test, and lighthouse-test. Install its dependencies with npm install in scripts/, run it inside the DDEV web container, and provide in-container browsers through the public codingsasi/ddev-playwright add-on (ddev add-on get codingsasi/ddev-playwright, then ddev install-playwright). A second bundled script, scripts/backend-module-sweep.cjs, proves after the upgrade that every backend module opens without errors (Phase 9). Read references/visual-regression.md for commands, thresholds, and tuning before the first run. When the bundled harness cannot run, scaffold Playwright toHaveScreenshot tests instead, with animations disabled and dynamic regions (dates, carousels, consent banners) masked or stabilized.Use only the skills relevant to the detected codebase, and run them sequentially so each pass sees the previous fixes. In clients that ship only legacy Cursor rules instead of skills, use the matching .cursor/rules/<skill>.mdc file for each step.
| Order | Skill | Apply when |
|---|---|---|
| 1 | typo3-ddev | Always; DDEV URLs, PHP and database version management, container workflow |
| 2 | typo3-extension-upgrade | Always; inventory, dependency planning, upgrade sequence |
| 3 | typo3-rector | Always; PHP migration, first dry-run and then reviewed apply |
| 4 | typo3-fractor | Always; Fluid, TypoScript, FlexForm, YAML, and other non-PHP migration |
| 5 | php-modernization | PHP types, language level, Rector, PHPStan, and code-style tooling |
| 6 | typo3-workspaces | Always audit workspace safety; add explicit workspace behavior when records, previews, files, or publishing are involved |
| 7 | typo3-conformance and typo3-simplify | Always; v14 architecture, obsolete files, Core API reuse, and code clarity |
| 8 | typo3-security and security-audit | Always; extension-specific and general security review |
| 9 | typo3-testing | Always; preserve behavior and add missing unit, functional, integration, workspace, and E2E coverage as appropriate |
| 10 | typo3-docs | Always; README, TYPO3 documentation, upgrade notes, and changelog |
Select additional TYPO3 skills after inventory: typo3-batch, typo3-content-blocks, typo3-datahandler, typo3-translations, typo3-accessibility, typo3-wcag22-aa-agentic, typo3-webcomponents, typo3-vite, typo3-icon14, typo3-visual-editor, typo3-powermail, typo3-solr, and typo3-seo. Do not run unrelated domain skills merely because they exist.
composer.json referencesaschaegerer/phpstan-typo3 releasesfileadmin imported into DDEV. Creating that sync is outside this skill: when it is missing or stale, ask the user for a fresh dump instead of connecting to production.ddev start, then ddev describe for PHP version, database engine and version, docroot, and project type. Determine the current TYPO3/PHP versions from composer.json, composer.lock, CI, .ddev/config.yaml, and legacy metadata. Do not infer versions from filenames alone.ddev snapshot --name pre-update plus an exported dump (ddev export-db > pre-update.sql.gz) stored outside the container.packages/, or no v14 release — as input for the extension update strategy.sitemap.xml for every configured site language before any update work: each language has its own reachable sitemap variant at the DDEV URL, entries use the correct base and language prefixes, hreflang and canonical configuration are consistent, every listed URL answers 200 and is indexable, and the expected page tree is covered without excluded types leaking in. Fix site configuration and EXT:seo settings first — the sitemaps are the sampling source for every following loop.bootstrap latest on the 5.3 line) and build it through the project's Vite pipeline with the typo3-vite skill. This is the one deliberate rendering change in the skill, so it runs as its own miniature regression loop:
typo3-wcag22-aa-agentic (axe-core through Playwright), apply fixes using typo3-accessibility patterns, and re-audit until WCAG 2.2 AA passes with zero critical axe violations. Accessibility fixes change markup too, which is why both land before the visual baselines: the baselines then capture the corrected state, and the update must preserve both pixels and accessibility.get-urls action against the DDEV URL (per-language sitemaps plus golden-path URLs, random fill, capped at 100), make sure the homepage and every distinct page type or template are represented, and persist the resulting URL file, device/viewport matrix (the harness shoots with Chromium), and settings so the identical sample re-runs after the update. Then shoot the baselines with take-screenshots.php_version in .ddev/config.yaml in step with the upgrade ladder — keep a version the currently installed core supports so the site boots, and switch to the project's PHP target of at least 8.4 no later than the ^14.3 rung, verifying supported versions against the 14.3 system requirements. Adjust database the same way when required; if the engine or version must change, follow DDEV's documented database migration path and re-import the baseline dump instead of editing configuration blindly. ddev restart after each change.typo3/cms-core: ^14.3, not ^14.0, because 14.3 is the supported LTS line and 14.0 through 14.2 no longer receive security updates. Require at least PHP 8.4: site projects run php: ^8.4 (or the exact production version), and only reusable packages that test and document a broader range may keep one. Keep config.platform.php in step with the ladder exactly like php_version: pin it to the PHP the container currently runs, and raise it to the 8.4 target at the ^14.3 rung — a platform pin ahead of the container makes Composer select packages the runtime cannot boot.^13.4, make the installation boot, and run all 13.4 core upgrade wizards and schema updates; only then require ^14.3. Save the full code modernization for the v14 rung. A v13 source, or a code-only package without persisted data, moves straight to ^14.3. Verify ddev typo3 upgrade:list is empty before leaving each rung.composer.json per TYPO3 feature #108345: ext_emconf.php is deprecated in v14 and no longer evaluated in v15. Remove the file for project-local extensions in packages/; keep it — exactly in sync with composer.json — only where a tool still requires it (TER/Tailor publishing) or the user explicitly requires a temporary v13 bridge.type: typo3-cms-extension, PSR-4 autoloading, and extra.typo3/cms.extension-key valid, and provide the package metadata #108345 makes mandatory from v15 (its absence raises a cache-warmup deprecation in v14): extra.typo3/cms.version — or the top-level version field — matching the future Git tag (do not create the tag), and extra.typo3/cms.Package.providesPackages as an empty object when the extension provides no Composer packages. In Classic mode, providesPackages may map a provided package to a relative Composer vendor directory whose autoload.php TYPO3 loads early; packages shipped by TYPO3 or provided by other loaded extensions are not listed. Express pre-stable state as version suffixes (1.2.3-beta2) and replace state = excludeFromUpdates with extra.typo3/cms.exclude-from-updates: true.replace entries for typo3-ter/* or the extension key when Composer validation flags them.saschaegerer/phpstan-typo3 through phpstan/extension-installer or its documented extension.neon; do not copy stale configuration from the repository.ddev composer validate --strict, update dependencies with the narrowest justified Composer command, and inspect the lockfile diff.Every installed extension gets updated — third-party and local alike. The site is only on v14 when its complete extension set resolves and works there. Classify each extension during the Phase 1 inventory and route it:
ddev composer why-not typo3/cms-core "^14.3" names every package still blocking the core jump; clear all blockers before requiring the new core.packages/: treat it as a first-class migration target. Keep it wired through the project's Composer path repository, raise its own composer.json to typo3/cms-core ^14.3 and the project's PHP target (at least ^8.4), and run the full pipeline — Rector, Fractor, manual migration, PHPStan, tests — inside that package like any other extension this skill upgrades.packages/ as a path-repository override, migrate it there locally, and record the fork as technical debt in the handover report.ddev snapshot, uninstall the extension (ddev composer remove), and measure what actually changes: frontend pages, content elements and plugins it provided, backend modules, scheduler tasks, TCA columns, and database tables left behind. If the site works without it, propose removing it permanently and let the user decide; document orphaned tables and columns for later cleanup. If the loss matters, restore the snapshot, reinstall, and either fix the extension in packages/ or replace its functionality before the completion gate. Never drop a feature silently.TYPO3_version branches, v12/v13 constraints, compatibility helpers, deprecated hooks with documented event replacements, legacy backend module registration, obsolete TypoScript, unused XLF keys, and dead imports.vite-asset-collector. TYPO3 v14 removed core asset concatenation and compression, so the Vite build owns bundling and minification; use typo3-vite for build configuration and skip its extension-based integration.^14.3 rung — the intermediate ^13.4 rung was already cleared inside the Phase 3 ladder — take a fresh ddev snapshot, then run ddev typo3 extension:setup (the Core command that performs the database schema migrations) and ddev typo3 upgrade:list followed by the reviewed upgrade:run steps. Review schema changes before applying them: use the backend database analyzer in Admin Tools, or preview with ddev typo3 database:updateschema "*.add,*.change" --dry-run when the project ships helhum/typo3-console — that command is not TYPO3 Core. The local database is the only database this skill migrates.referenceindex:update, language:update), then flush and warm caches (cache:flush, cache:warmup). Cache warm-up must not emit the #108345 package-metadata deprecation — when it does, fix the extension's composer.json (version / providesPackages) instead of ignoring the message.Run each applicable feature block after the core upgrade and before closing the visual loop. After every block, re-shoot the affected sample pages: an intentional rendering change needs explicit user approval and a recorded baseline refresh; everything else must stay pixel-identical.
Solr — when the site uses EXT:solr: read the EXT:solr version matrix for the release row matching TYPO3 14.3, update the local DDEV Solr service through the official ddev/ddev-solr add-on to that Apache Solr version with the matching configset, and update EXT:solr, search templates, and configuration following the typo3-solr skill. Require the 14 line with a per-package stability flag — ddev composer require apache-solr-for-typo3/solr:"^14.0@RC" — because that line is currently a release candidate. The flag keeps the project's global minimum-stability: stable and prefer-stable: true intact, loosening stability for this one package only, and it needs no later edit: Composer prefers the stable 14.0.0 automatically as soon as it ships. Verify the resolved version and its TYPO3 requirement before continuing, and never loosen global stability to install a single package. Rebuild the index queue and reindex fully; the backend Info module must show the site as active, and frontend search — including empty and paginated results — is re-verified.
Visual Editor: require the latest v14-compatible friendsoftypo3/visual-editor release, verified on Packagist at execution time, and migrate the Fluid templates with the typo3-visual-editor skill (f:render.text, content areas, colPos migration). Verify inline editing works on a representative page in the backend; the migration must not change frontend rendering — the visual sample proves it.
CKEditor RTE: migrate old RTE presets into the current v14 rte_ckeditor YAML — import the old settings, drop obsolete keys, and verify every option against the installed version. Enable text part language so editors can mark passages with <span lang="…"> for the site's configured languages, and add abbreviation support through a maintained CKEditor 5 plugin extension found on TER or Packagist and verified against v14 — never guess plugin package names. Align the editor's content styles with the live site's frontend styles, but scale down oversized elements (for example very large h2 headings) for editing ergonomics.
Semantic markup that nobody can see does not survive the next editing round, so both features need styling on both sides:
editor.config.contentsCss in the preset: give abbr[title] and span[lang] a visible affordance in the editing area — for example a dotted underline plus cursor: help for abbreviations and a subtle marker for language spans — so editors can find, verify, and maintain the markup they inserted. TYPO3 v14 renders CKEditor inline and auto-prefixes this file client-side, so :root and body rules work and resolve to the .ck-content scope. The file is browser-cached: append a ?v= parameter to the path and bump it after every change, otherwise edits appear to have no effect.abbr[title] a consistent affordance across browsers, whose native rendering is inconsistent, and keep the expansion understandable without hover since touch and keyboard users cannot hover. Leave span[lang] visually unstyled — it is semantic markup for assistive technology, not decoration for readers — but let the attribute do its typographic work through :lang() rules for hyphenation, quotation marks, and font stack.Frontend CSS changes rendering, so this block follows the re-shoot and approval rule above. Then verify live in the backend: open a rich-text content element and confirm the preset loads with the language and abbreviation controls, applies the intended styling, and shows the affordances on marked-up text; confirm the same markup renders correctly in the frontend, and that the Phase 8 accessibility re-check stays green.
Security headers and checklist: apply the typo3-security skill's checklist — security headers (HSTS, X-Content-Type-Options, X-Frame-Options/frame-ancestors, Referrer-Policy, Permissions-Policy), trustedHostsPattern, backend hardening, and CSP through the TYPO3 v14 CSP API — configured at a single layer without conflicting duplicates. Verify the header values on DDEV responses; differences that only exist on production layers (proxy, CDN) belong in the deployment handover and are never applied to live from here.
take-screenshots, using the identical URL file, browser/device matrix, and settings.compare-screenshots. The engine's minor-diff tolerance absorbs sub-pixel anti-aliasing noise; anything above it — layout, spacing, font, color, or content — is a defect, because the same content on the same database must render identically by definition.ddev composer audit; unresolved security advisories block completion.ddev composer install from the committed lockfile must resolve against TYPO3 14.3 and the claimed PHP versions.ddev composer why-not php 8.4 must name no blocker, every local or forked extension in packages/ declares the PHP target in its own composer.json, PHPStan runs with phpVersion set to the target, and lint plus all test suites execute in the PHP 8.4 (or newer) container while the TYPO3 deprecation log stays clean. Any extension that blocks the PHP target goes back through the extension update strategy — upgraded, forked and patched in packages/, or removed with approval.EXT:solr is used), login and password recovery, forms, the 404 response, robots.txt, and every sitemap entry point; the harness's smoke-test action (random link clicking) adds broad-coverage navigation on top. DDEV routes all outgoing mail to Mailpit (ddev launch -m), so form finishers and recovery mails are verified there and no real recipient is ever contacted.scripts/backend-module-sweep.cjs: it logs in at the DDEV URL, discovers every module from the module menu, opens each one, and fails on exception output, server errors, or severe console errors, writing a JSON report for the KPI report. Every module must pass; trace a failing module to its owning extension and route it back through the extension update strategy, and check the TYPO3 log for entries the sweep triggered.ddev typo3 scheduler:run) and confirm they succeed with any mail landing in Mailpit; check that EXT:redirects entries resolve without loops or dead targets; run linkvalidator where installed and triage broken links; review sys_log and the deprecation log for errors raised since the update.EXT:seo and TYPO3 rendering APIs where they cover the requirement. Expect DDEV-local URLs in the output; flag absolute-URL configuration that must change per environment in the handover notes.get-urls; the harness's lighthouse-test action covers a quick pass over the homepage plus a few random sitemap pages — loop Lighthouse over the persisted URL list for the full sample) and run it against the DDEV URL in a clean, extension-free browser profile, recording version, URLs, viewport, timestamp, scores, and Core Web Vitals. Loop — fix, re-measure the affected pages — until findings are resolved or explicitly justified: enable AVIF through GFX/imageFileConversionFormats and avif_quality when the installed processor reports AVIF write support, preload only resources critical to the measured LCP with exactly matching URLs, give the LCP image eager loading and fetchpriority="high", and keep minification in the Vite build (Phase 5 owns that pipeline; v14 removed the core equivalents). Treat local absolute scores as indicative; act on concrete findings, and re-baseline approved visual changes per the main loop rules.README.md as the concise entry point: purpose, features, TYPO3/PHP requirements, installation, quick start, configuration, workspace behavior, testing, limitations, and links to detailed docs. Update Documentation/ using TYPO3 conventions with a v12/v13-to-v14 upgrade guide, migration commands, data upgrade steps, breaking changes, and removed features.CHANGELOG.md entry describing the v14.3-only requirement, dropped versions, dependency changes, workspace support, and migrations. Do not invent a release date or tag.docs/audits/ only when the repository already uses that convention or the user requests an audit artifact.webconsulting-branding and the available docx-generation skill. Required sections: Before and after the update — TYPO3/PHP versions, extension set changes from the strategy, visual-diff count ending at zero, backend module sweep results, accessibility results, Lighthouse scores and Core Web Vitals; Data — sitemap coverage per language, the persisted sample URL lists, response codes, image formats and AVIF share, PHPStan level, test and audit results; Recommendations — information architecture with concrete examples and the reasoning behind each, design improvements shown as before/after pairs from the regression screenshots, easy optimization wins (for example correct ImageMagick/GraphicsMagick GFX configuration), and anything else worth flagging such as caching, security headers, SEO, or content quality. Recommendations are proposals for the user, not changes this skill makes.Finish only when all applicable items are true:
EXT:solr, the resolved extension is the newest 14 release (release candidates allowed through a per-package stability flag, never through global minimum-stability), the local Solr server runs the matrix-supported version, the index is fully rebuilt, and the Info module shows the site as active.abbr[title] plus span[lang] are styled in both the editing area (contentsCss) and the frontend, with language spans left visually undecorated.ddev composer install from the lockfile resolves against TYPO3 14.3 and the claimed PHP versions; composer validate --strict and composer audit pass.composer why-not php 8.4 names no blocker, and lint, PHPStan, and all tests ran in the PHP 8.4 (or newer) container with a clean deprecation log.packages/, or removed with recorded user approval; none is left unresolved.README.md, Documentation/, and CHANGELOG.md agree with composer.json and actual behavior, the final report includes the deployment handover section, and the webconsulting-CI Word KPI report with before/after, data, and recommendation sections is delivered.If a gate cannot run, state exactly why, show the evidence available, and leave the task incomplete rather than claiming success.
npx claudepluginhub dirnbauer/webconsulting-skillsAnalyzes, plans, and executes TYPO3 v13 to v14 upgrades in Composer-based projects: checks extension compatibility, deprecations, Rector/Fractor migrations, and system requirements.
Simplifies and refines TYPO3 extension code (PHP, Fluid, TCA, YAML) for v14 best practices, replacing deprecated patterns with core APIs. Run after implementing a feature or before merging a PR.
Guides collaborative design exploration before implementation: explores context, asks clarifying questions, proposes approaches, and writes a design doc for user approval.