{"id":62,"date":"2026-10-17T07:00:00","date_gmt":"2026-10-17T07:00:00","guid":{"rendered":"https:\/\/myport.ddev.site\/blog\/life-without-tsfe-in-typo3-v13-and-v14\/"},"modified":"2026-10-16T12:00:12","modified_gmt":"2026-10-16T12:00:12","slug":"life-without-tsfe-in-typo3-v13-and-v14","status":"publish","type":"post","link":"https:\/\/hoja.in\/blog\/life-without-tsfe-in-typo3-v13-and-v14\/","title":{"rendered":"Life without $GLOBALS[&#8216;TSFE&#8217;] in TYPO3 v13 and v14"},"content":{"rendered":"<p>For almost twenty years, every TYPO3 developer had one friend who was always there: <code>$GLOBALS['TSFE']<\/code>. Page id, language, TypoScript, the current content object, header data, cache settings. Everything was in that one object, reachable from anywhere.<\/p>\n<p>That friend is gone. TYPO3 13.4 deprecated the <code>TypoScriptFrontendController<\/code> and <code>$GLOBALS['TSFE']<\/code> (Deprecation #105230), and TYPO3 14.0 removed the global and all ways to get the instance (Breaking #107831). In the 14.3.9 installation I work with, the class file is not even in <code>cms-frontend<\/code> any more. Old extension code that touches it now ends with a fatal error.<\/p>\n<p>The good news: almost everything you needed is now a PSR-7 request attribute. This post shows the replacements I use most, in an Extbase controller, a middleware and a ViewHelper.<\/p>\n<h2>The mapping table<\/h2>\n<p>These come from the changelog entry Breaking #102621, which lists every TSFE member and its replacement. The ones I meet in nearly every upgrade:<\/p>\n<ul>\n<li><code>$GLOBALS['TSFE']-&gt;id<\/code> \u2192 <code>$request-&gt;getAttribute('frontend.page.information')-&gt;getId()<\/code><\/li>\n<li><code>$GLOBALS['TSFE']-&gt;page<\/code> \u2192 <code>...-&gt;getPageRecord()<\/code> on the same object<\/li>\n<li><code>$GLOBALS['TSFE']-&gt;rootLine<\/code> \u2192 <code>...-&gt;getRootLine()<\/code><\/li>\n<li><code>$GLOBALS['TSFE']-&gt;getLanguage()<\/code> \u2192 <code>$request-&gt;getAttribute('language')<\/code><\/li>\n<li><code>$GLOBALS['TSFE']-&gt;getSite()<\/code> \u2192 <code>$request-&gt;getAttribute('site')<\/code><\/li>\n<li><code>$GLOBALS['TSFE']-&gt;getPageArguments()<\/code> \u2192 <code>$request-&gt;getAttribute('routing')<\/code><\/li>\n<li><code>$GLOBALS['TSFE']-&gt;config['config']<\/code> \u2192 <code>$request-&gt;getAttribute('frontend.typoscript')-&gt;getConfigArray()<\/code><\/li>\n<li><code>$GLOBALS['TSFE']-&gt;tmpl-&gt;setup<\/code> \u2192 <code>$request-&gt;getAttribute('frontend.typoscript')-&gt;getSetupArray()<\/code><\/li>\n<li><code>set_no_cache()<\/code> \u2192 <code>$request-&gt;getAttribute('frontend.cache.instruction')-&gt;disableCache('reason')<\/code><\/li>\n<li><code>additionalHeaderData[]<\/code> \u2192 <code>PageRenderer::addHeaderData()<\/code><\/li>\n<\/ul>\n<p>The pattern is always the same: find where you can get the request, then ask it.<\/p>\n<h2>In an Extbase controller<\/h2>\n<p>Before, in a typical old controller:<\/p>\n<pre><code class=\"language-php\">public function listAction(): ResponseInterface\n{\n    $pageId = (int)$GLOBALS['TSFE']-&gt;id;\n    $languageId = $GLOBALS['TSFE']-&gt;getLanguage()-&gt;getLanguageId();\n    $items = $this-&gt;itemRepository-&gt;findByPageAndLanguage($pageId, $languageId);\n    $this-&gt;view-&gt;assign('items', $items);\n    return $this-&gt;htmlResponse();\n}<\/code><\/pre>\n<p>After. The Extbase request is a full PSR-7 request, so the attributes are right there:<\/p>\n<pre><code class=\"language-php\">use TYPO3CMSCoreSiteEntitySiteLanguage;\nuse TYPO3CMSFrontendPagePageInformation;\n\npublic function listAction(): ResponseInterface\n{\n    \/** @var PageInformation $pageInformation *\/\n    $pageInformation = $this-&gt;request-&gt;getAttribute('frontend.page.information');\n    \/** @var SiteLanguage $language *\/\n    $language = $this-&gt;request-&gt;getAttribute('language');\n\n    $items = $this-&gt;itemRepository-&gt;findByPageAndLanguage(\n        $pageInformation-&gt;getId(),\n        $language-&gt;getLanguageId()\n    );\n    $this-&gt;view-&gt;assign('items', $items);\n    return $this-&gt;htmlResponse();\n}<\/code><\/pre>\n<p>This works the same in 13.4 and 14.3, so you can migrate before you upgrade. That is the order I recommend: clean up on v13 with the deprecation log open, then jump.<\/p>\n<h2>In a middleware<\/h2>\n<p>Middlewares are where people get surprised. An attribute exists only after the middleware that sets it. <code>frontend.page.information<\/code> is set by the page resolver, and <code>frontend.typoscript<\/code> by <code>typo3\/cms-frontend\/prepare-tsfe-rendering<\/code>. So register your middleware after that one:<\/p>\n<pre><code class=\"language-php\">&lt;?php\n\/\/ Configuration\/RequestMiddlewares.php\nreturn [\n    'frontend' =&gt; [\n        'myvendor\/my-ext\/page-header' =&gt; [\n            'target' =&gt; MyVendorMyExtMiddlewarePageHeaderMiddleware::class,\n            'after' =&gt; [\n                'typo3\/cms-frontend\/prepare-tsfe-rendering',\n            ],\n        ],\n    ],\n];<\/code><\/pre>\n<pre><code class=\"language-php\">&lt;?php\n\ndeclare(strict_types=1);\n\nnamespace MyVendorMyExtMiddleware;\n\nuse PsrHttpMessageResponseInterface;\nuse PsrHttpMessageServerRequestInterface;\nuse PsrHttpServerMiddlewareInterface;\nuse PsrHttpServerRequestHandlerInterface;\nuse TYPO3CMSCoreRoutingPageArguments;\nuse TYPO3CMSFrontendPagePageInformation;\n\nfinal class PageHeaderMiddleware implements MiddlewareInterface\n{\n    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface\n    {\n        $response = $handler-&gt;handle($request);\n\n        $pageInformation = $request-&gt;getAttribute('frontend.page.information');\n        $routing = $request-&gt;getAttribute('routing');\n        if (!$pageInformation instanceof PageInformation || !$routing instanceof PageArguments) {\n            return $response;\n        }\n\n        $config = $request-&gt;getAttribute('frontend.typoscript')?-&gt;getConfigArray() ?? [];\n        if ((bool)($config['tx_myext.']['sendPageHeader'] ?? false)) {\n            $response = $response\n                -&gt;withHeader('X-Page-Id', (string)$pageInformation-&gt;getId())\n                -&gt;withHeader('X-Page-Type', $routing-&gt;getPageType());\n        }\n        return $response;\n    }\n}<\/code><\/pre>\n<p>One trap here: I used <code>getConfigArray()<\/code> on purpose. The full setup array from <code>getSetupArray()<\/code> is only built when TYPO3 really renders something. When the page comes completely from the cache, calling it throws a <code>RuntimeException<\/code>. The <code>config.<\/code> part is always available after the prepare middleware, so a middleware should read its switches from there.<\/p>\n<h2>In a ViewHelper<\/h2>\n<p>ViewHelpers have no <code>$this-&gt;request<\/code>. In TYPO3 13 you could still call <code>$this-&gt;renderingContext-&gt;getRequest()<\/code>, but that was deprecated in 13.3 (Deprecation #104684) and is gone in 14. The way that works in both versions is the attribute API of the rendering context:<\/p>\n<pre><code class=\"language-php\">&lt;?php\n\ndeclare(strict_types=1);\n\nnamespace MyVendorMyExtViewHelpers;\n\nuse PsrHttpMessageServerRequestInterface;\nuse TYPO3CMSCoreSiteEntitySiteLanguage;\nuse TYPO3FluidFluidCoreViewHelperAbstractViewHelper;\n\n\/**\n * Usage: {my:languageCode()} renders e.g. \"en-US\"\n *\/\nfinal class LanguageCodeViewHelper extends AbstractViewHelper\n{\n    public function render(): string\n    {\n        if (!$this-&gt;renderingContext-&gt;hasAttribute(ServerRequestInterface::class)) {\n            return '';\n        }\n        $request = $this-&gt;renderingContext-&gt;getAttribute(ServerRequestInterface::class);\n        $language = $request-&gt;getAttribute('language');\n\n        return $language instanceof SiteLanguage\n            ? $language-&gt;getLocale()-&gt;getName()\n            : '';\n    }\n}<\/code><\/pre>\n<p>Before, this ViewHelper was one line with <code>$GLOBALS['TSFE']-&gt;getLanguage()<\/code>. Now it is a few lines longer, but it also works when the ViewHelper is rendered in a context without a frontend request, for example in a mail template from a CLI command. It just returns an empty string instead of crashing.<\/p>\n<h2>What about the content object?<\/h2>\n<p><code>$GLOBALS['TSFE']-&gt;cObj<\/code> is another classic. The changelog advice is to create your own <code>ContentObjectRenderer<\/code>, call <code>setRequest($request)<\/code>, and <code>start()<\/code> it with the page record from <code>frontend.page.information<\/code>. In Extbase controllers you rarely need it at all; most of the time a <code>typolink<\/code> is better done with the <code>LinkFactory<\/code> or a ViewHelper in the template.<\/p>\n<h2>Testing code that reads request attributes<\/h2>\n<p>A nice side effect: code that takes the request as input is easy to test. In a unit test you can build a <code>ServerRequest<\/code>, add a <code>PageInformation<\/code> object (its <code>setId()<\/code> is marked internal for the core, but fine in a test) and a <code>SiteLanguage<\/code> as attributes, and call your middleware or service directly. With <code>$GLOBALS['TSFE']<\/code> you had to fake a global god object first, and most people simply did not write the test.<\/p>\n<h2>How I find all the places<\/h2>\n<ol>\n<li>On v13, enable the deprecation log and click through the site. TSFE access logs a lot.<\/li>\n<li>Run the Extension Scanner in the upgrade module of the install tool. It knows these patterns.<\/li>\n<li>Search the code: <code>grep -rn \"TSFE|getTypoScriptFrontendController|frontend.controller\" Classes\/<\/code>. Also check TypoScript conditions: <code>getTSFE()<\/code> in conditions was removed in v14 too (Breaking #107473).<\/li>\n<li>Run Rector with the TYPO3 rule sets for the simple cases, and review every change by hand.<\/li>\n<\/ol>\n<p>The removal felt painful at first. But after a few extensions I started to like it: every dependency is now visible in the method signature or the request, and tests became easier because I can pass a request with exactly the attributes I need. Feedbacks are the champion&#8217;s breakfast, so tell me in the comments which TSFE call gave you the most trouble.<\/p>\n<h2>Further reading<\/h2>\n<ul>\n<li><a href=\"https:\/\/docs.typo3.org\/c\/typo3\/cms-core\/main\/en-us\/Changelog\/14.0\/Breaking-107831-RemovedTypoScriptFrontendController.html\">Breaking #107831: Removed TypoScriptFrontendController<\/a><\/li>\n<li><a href=\"https:\/\/docs.typo3.org\/c\/typo3\/cms-core\/main\/en-us\/Changelog\/13.0\/Breaking-102621-MostTSFEMembersMarkedInternalOrRead-only.html\">Breaking #102621: TSFE members and their replacements<\/a><\/li>\n<li><a href=\"https:\/\/docs.typo3.org\/m\/typo3\/reference-coreapi\/main\/en-us\/ApiOverview\/RequestLifeCycle\/RequestAttributes\/Index.html\">TYPO3: Request attributes<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>TYPO3 v14 removed $GLOBALS[&#8216;TSFE&#8217;]. Here is how page id, language, TypoScript and routing data come from PSR-7 request attributes in controllers, middlewares and ViewHelpers.<\/p>\n","protected":false},"author":1,"featured_media":63,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[17],"tags":[30,32,33,24,25],"class_list":["post-62","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-typo3","tag-extension-development","tag-php-8","tag-typo3-v13","tag-typo3-v14","tag-upgrades"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.7 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Replacing $GLOBALS[&#039;TSFE&#039;] in TYPO3 v13 and v14<\/title>\n<meta name=\"description\" content=\"TSFE is gone in TYPO3 v14. Before\/after code for page id, language, TypoScript and routing via request attributes in Extbase, middlewares and ViewHelpers.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/hoja.in\/blog\/life-without-tsfe-in-typo3-v13-and-v14\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Replacing $GLOBALS[&#039;TSFE&#039;] in TYPO3 v13 and v14\" \/>\n<meta property=\"og:description\" content=\"TSFE is gone in TYPO3 v14. Before\/after code for page id, language, TypoScript and routing via request attributes in Extbase, middlewares and ViewHelpers.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/hoja.in\/blog\/life-without-tsfe-in-typo3-v13-and-v14\/\" \/>\n<meta property=\"og:site_name\" content=\"Hoja Mustaffa Abdul Latheef \u2013 Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-10-17T07:00:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/hoja.in\/blog\/wp-content\/uploads\/2026\/10\/life-without-tsfe-in-typo3-v13-and-v14.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Hoja Mustaffa Abdul Latheef\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@hojaonline\" \/>\n<meta name=\"twitter:site\" content=\"@hojaonline\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Hoja Mustaffa Abdul Latheef\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/life-without-tsfe-in-typo3-v13-and-v14\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/life-without-tsfe-in-typo3-v13-and-v14\\\/\"},\"author\":{\"name\":\"Hoja Mustaffa Abdul Latheef\",\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/#\\\/schema\\\/person\\\/e6fbd54c2061674d8ea3e7861d858c7b\"},\"headline\":\"Life without $GLOBALS[&#8216;TSFE&#8217;] in TYPO3 v13 and v14\",\"datePublished\":\"2026-10-17T07:00:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/life-without-tsfe-in-typo3-v13-and-v14\\\/\"},\"wordCount\":665,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/#\\\/schema\\\/person\\\/e6fbd54c2061674d8ea3e7861d858c7b\"},\"image\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/life-without-tsfe-in-typo3-v13-and-v14\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/hoja.in\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/life-without-tsfe-in-typo3-v13-and-v14.jpg\",\"keywords\":[\"Extension development\",\"PHP 8\",\"TYPO3 v13\",\"TYPO3 v14\",\"Upgrades\"],\"articleSection\":[\"TYPO3\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/hoja.in\\\/blog\\\/life-without-tsfe-in-typo3-v13-and-v14\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/life-without-tsfe-in-typo3-v13-and-v14\\\/\",\"url\":\"https:\\\/\\\/hoja.in\\\/blog\\\/life-without-tsfe-in-typo3-v13-and-v14\\\/\",\"name\":\"Replacing $GLOBALS['TSFE'] in TYPO3 v13 and v14\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/life-without-tsfe-in-typo3-v13-and-v14\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/life-without-tsfe-in-typo3-v13-and-v14\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/hoja.in\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/life-without-tsfe-in-typo3-v13-and-v14.jpg\",\"datePublished\":\"2026-10-17T07:00:00+00:00\",\"description\":\"TSFE is gone in TYPO3 v14. Before\\\/after code for page id, language, TypoScript and routing via request attributes in Extbase, middlewares and ViewHelpers.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/life-without-tsfe-in-typo3-v13-and-v14\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/hoja.in\\\/blog\\\/life-without-tsfe-in-typo3-v13-and-v14\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/life-without-tsfe-in-typo3-v13-and-v14\\\/#primaryimage\",\"url\":\"https:\\\/\\\/hoja.in\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/life-without-tsfe-in-typo3-v13-and-v14.jpg\",\"contentUrl\":\"https:\\\/\\\/hoja.in\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/life-without-tsfe-in-typo3-v13-and-v14.jpg\",\"width\":1200,\"height\":630,\"caption\":\"Goodbye TSFE\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/life-without-tsfe-in-typo3-v13-and-v14\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/hoja.in\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Life without $GLOBALS[&#8216;TSFE&#8217;] in TYPO3 v13 and v14\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/hoja.in\\\/blog\\\/\",\"name\":\"Hoja Mustaffa Abdul Latheef \u2013 Blog\",\"description\":\"Notes from daily work with TYPO3, PHP and AI-assisted engineering\",\"publisher\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/#\\\/schema\\\/person\\\/e6fbd54c2061674d8ea3e7861d858c7b\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/hoja.in\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/#\\\/schema\\\/person\\\/e6fbd54c2061674d8ea3e7861d858c7b\",\"name\":\"Hoja Mustaffa Abdul Latheef\",\"logo\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/#\\\/schema\\\/person\\\/image\\\/\"},\"description\":\"Senior TYPO3 Developer at jweiland.net, TYPO3 CMS Certified Developer. I write about TYPO3 upgrades, extension development, PHP and AI-assisted engineering with Claude Code.\",\"sameAs\":[\"https:\\\/\\\/hoja.in\\\/\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Replacing $GLOBALS['TSFE'] in TYPO3 v13 and v14","description":"TSFE is gone in TYPO3 v14. Before\/after code for page id, language, TypoScript and routing via request attributes in Extbase, middlewares and ViewHelpers.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/hoja.in\/blog\/life-without-tsfe-in-typo3-v13-and-v14\/","og_locale":"en_US","og_type":"article","og_title":"Replacing $GLOBALS['TSFE'] in TYPO3 v13 and v14","og_description":"TSFE is gone in TYPO3 v14. Before\/after code for page id, language, TypoScript and routing via request attributes in Extbase, middlewares and ViewHelpers.","og_url":"https:\/\/hoja.in\/blog\/life-without-tsfe-in-typo3-v13-and-v14\/","og_site_name":"Hoja Mustaffa Abdul Latheef \u2013 Blog","article_published_time":"2026-10-17T07:00:00+00:00","og_image":[{"width":1200,"height":630,"url":"https:\/\/hoja.in\/blog\/wp-content\/uploads\/2026\/10\/life-without-tsfe-in-typo3-v13-and-v14.jpg","type":"image\/jpeg"}],"author":"Hoja Mustaffa Abdul Latheef","twitter_card":"summary_large_image","twitter_creator":"@hojaonline","twitter_site":"@hojaonline","twitter_misc":{"Written by":"Hoja Mustaffa Abdul Latheef","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/hoja.in\/blog\/life-without-tsfe-in-typo3-v13-and-v14\/#article","isPartOf":{"@id":"https:\/\/hoja.in\/blog\/life-without-tsfe-in-typo3-v13-and-v14\/"},"author":{"name":"Hoja Mustaffa Abdul Latheef","@id":"https:\/\/hoja.in\/blog\/#\/schema\/person\/e6fbd54c2061674d8ea3e7861d858c7b"},"headline":"Life without $GLOBALS[&#8216;TSFE&#8217;] in TYPO3 v13 and v14","datePublished":"2026-10-17T07:00:00+00:00","mainEntityOfPage":{"@id":"https:\/\/hoja.in\/blog\/life-without-tsfe-in-typo3-v13-and-v14\/"},"wordCount":665,"commentCount":0,"publisher":{"@id":"https:\/\/hoja.in\/blog\/#\/schema\/person\/e6fbd54c2061674d8ea3e7861d858c7b"},"image":{"@id":"https:\/\/hoja.in\/blog\/life-without-tsfe-in-typo3-v13-and-v14\/#primaryimage"},"thumbnailUrl":"https:\/\/hoja.in\/blog\/wp-content\/uploads\/2026\/10\/life-without-tsfe-in-typo3-v13-and-v14.jpg","keywords":["Extension development","PHP 8","TYPO3 v13","TYPO3 v14","Upgrades"],"articleSection":["TYPO3"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/hoja.in\/blog\/life-without-tsfe-in-typo3-v13-and-v14\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/hoja.in\/blog\/life-without-tsfe-in-typo3-v13-and-v14\/","url":"https:\/\/hoja.in\/blog\/life-without-tsfe-in-typo3-v13-and-v14\/","name":"Replacing $GLOBALS['TSFE'] in TYPO3 v13 and v14","isPartOf":{"@id":"https:\/\/hoja.in\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/hoja.in\/blog\/life-without-tsfe-in-typo3-v13-and-v14\/#primaryimage"},"image":{"@id":"https:\/\/hoja.in\/blog\/life-without-tsfe-in-typo3-v13-and-v14\/#primaryimage"},"thumbnailUrl":"https:\/\/hoja.in\/blog\/wp-content\/uploads\/2026\/10\/life-without-tsfe-in-typo3-v13-and-v14.jpg","datePublished":"2026-10-17T07:00:00+00:00","description":"TSFE is gone in TYPO3 v14. Before\/after code for page id, language, TypoScript and routing via request attributes in Extbase, middlewares and ViewHelpers.","breadcrumb":{"@id":"https:\/\/hoja.in\/blog\/life-without-tsfe-in-typo3-v13-and-v14\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/hoja.in\/blog\/life-without-tsfe-in-typo3-v13-and-v14\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/hoja.in\/blog\/life-without-tsfe-in-typo3-v13-and-v14\/#primaryimage","url":"https:\/\/hoja.in\/blog\/wp-content\/uploads\/2026\/10\/life-without-tsfe-in-typo3-v13-and-v14.jpg","contentUrl":"https:\/\/hoja.in\/blog\/wp-content\/uploads\/2026\/10\/life-without-tsfe-in-typo3-v13-and-v14.jpg","width":1200,"height":630,"caption":"Goodbye TSFE"},{"@type":"BreadcrumbList","@id":"https:\/\/hoja.in\/blog\/life-without-tsfe-in-typo3-v13-and-v14\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/hoja.in\/blog\/"},{"@type":"ListItem","position":2,"name":"Life without $GLOBALS[&#8216;TSFE&#8217;] in TYPO3 v13 and v14"}]},{"@type":"WebSite","@id":"https:\/\/hoja.in\/blog\/#website","url":"https:\/\/hoja.in\/blog\/","name":"Hoja Mustaffa Abdul Latheef \u2013 Blog","description":"Notes from daily work with TYPO3, PHP and AI-assisted engineering","publisher":{"@id":"https:\/\/hoja.in\/blog\/#\/schema\/person\/e6fbd54c2061674d8ea3e7861d858c7b"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/hoja.in\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/hoja.in\/blog\/#\/schema\/person\/e6fbd54c2061674d8ea3e7861d858c7b","name":"Hoja Mustaffa Abdul Latheef","logo":{"@id":"https:\/\/hoja.in\/blog\/#\/schema\/person\/image\/"},"description":"Senior TYPO3 Developer at jweiland.net, TYPO3 CMS Certified Developer. I write about TYPO3 upgrades, extension development, PHP and AI-assisted engineering with Claude Code.","sameAs":["https:\/\/hoja.in\/"]}]}},"_links":{"self":[{"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/posts\/62","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/comments?post=62"}],"version-history":[{"count":1,"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/posts\/62\/revisions"}],"predecessor-version":[{"id":154,"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/posts\/62\/revisions\/154"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/media\/63"}],"wp:attachment":[{"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/media?parent=62"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/categories?post=62"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/tags?post=62"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}