How to Build TYPO3 Site Packages with PAGEVIEW and Site Sets in v13?

Modern TYPO3 development combines PAGEVIEW's streamlined rendering with Site Sets' configuration power. Build maintainable site packages that scale across multiple sites effortlessly.

TYPO3 v13 changed how we think about site packages. PAGEVIEW simplified page rendering while Site Sets revolutionized configuration management. But how do you combine them effectively?

Let's build a real site package that uses both features properly.

What Changed in TYPO3 v13

Before v13, site packages meant complex TypoScript configurations and scattered template files. Site configuration lived in YAML files that were hard to share between projects.

PAGEVIEW removes most TypoScript complexity. Site Sets make configurations portable and reusable. Together, they create cleaner, more maintainable code.

Setting Up Your Site Package Structure

Create your extension structure first:

my_site_package/
├── Configuration/
│   ├── Sets/
│   │   └── MyTheme/
│   │       ├── config.yaml
│   │       ├── page.tsconfig
│   │       └── setup.typoscript
│   ├── TCA/
│   └── TypoScript/
├── Resources/
│   ├── Private/
│   │   ├── Templates/
│   │   │   └── Page/
│   │   ├── Partials/
│   │   └── Layouts/
│   └── Public/
│       ├── Css/
│       ├── JavaScript/
│       └── Images/
└── ext_emconf.php

Creating Your First Site Set

Site Sets replace the old static template approach. Create Configuration/Sets/MyTheme/config.yaml:

name: my-theme
label: My Corporate Theme
dependencies:
  - typo3/fluid-styled-content
  - typo3/seo
settings:
  website:
    logo: EXT:my_site_package/Resources/Public/Images/logo.svg
    colors:
      primary: '#0066cc'
      secondary: '#f8f9fa'

The dependencies automatically load required functionality. No more hunting through static templates.

PAGEVIEW Template Setup

PAGEVIEW uses a simple template approach. Create your page template at Resources/Private/Templates/Page/Default.html:

<html lang="{site.language.twoLetterIsoCode}" data-namespace-typo3-fluid="true">
<f:layout name="Default" />

<f:section name="Main">
    <div class="container">
        <header class="site-header">
            <f:image src="{settings.website.logo}" alt="{site.websiteTitle}" class="logo" />
            <f:cObject typoscriptObjectPath="lib.navigation" />
        </header>
        
        <main class="content">
            <h1>{page.title}</h1>
            <f:cObject typoscriptObjectPath="lib.content.main" />
        </main>
    </div>
</f:section>
</html>

Notice how we access Site Set settings directly with {settings.website.logo}. Much cleaner than old TypoScript constants.

Minimal TypoScript Configuration

With PAGEVIEW, your TypoScript becomes minimal. Create Configuration/Sets/MyTheme/setup.typoscript:

# Page object - PAGEVIEW handles most rendering
page = PAGE
page {
    typeNum = 0
    
    # PAGEVIEW template
    10 = PAGEVIEW
    10 {
        templateRootPaths.10 = EXT:my_site_package/Resources/Private/Templates/
        partialRootPaths.10 = EXT:my_site_package/Resources/Private/Partials/
        layoutRootPaths.10 = EXT:my_site_package/Resources/Private/Layouts/
        
        variables {
            content < styles.content.get
        }
    }
    
    # CSS and JS
    includeCSS.theme = EXT:my_site_package/Resources/Public/Css/theme.css
    includeJS.theme = EXT:my_site_package/Resources/Public/JavaScript/theme.js
}

# Simple navigation
lib.navigation = HMENU
lib.navigation {
    1 = TMENU
    1.NO.linkWrap = <li>|</li>
    1.ACT = 1
    1.ACT.linkWrap = <li class="active">|</li>
    wrap = <ul class="nav">|</ul>
}

# Content rendering
lib.content.main < styles.content.get

That's it. No complex rendering definitions or content object configurations.

Page TSconfig in Site Sets

Add page-specific configuration to Configuration/Sets/MyTheme/page.tsconfig:

# Backend layout
mod.web_layout.BackendLayouts {
    default {
        title = Default Layout
        icon = EXT:my_site_package/Resources/Public/Images/backend_layout.svg
        config {
            backend_layout {
                colCount = 1
                rowCount = 2
                rows {
                    1 {
                        columns.1 {
                            name = Header
                            colPos = 1
                        }
                    }
                    2 {
                        columns.1 {
                            name = Main Content
                            colPos = 0
                        }
                    }
                }
            }
        }
    }
}

# Content element restrictions
TCEFORM.tt_content {
    CType.removeItems = div,html
    layout.altLabels {
        1 = Highlighted
        2 = Boxed Content
    }
}

Site Configuration Integration

Create your site configuration at config/sites/main/config.yaml and reference your Site Set:

rootPageId: 1
base: 'https://example.com/'
languages:
  -
    title: English
    enabled: true
    languageId: 0
    base: /
    typo3Language: default
    locale: en_US.UTF-8
    iso-639-1: en
    navigationTitle: English
    hreflang: en-US
    flag: us

dependencies:
  - my-theme

settings:
  website:
    contactEmail: info@example.com
    socialMedia:
      twitter: '@example'
      linkedin: 'company/example'

Site-specific settings override Site Set defaults. This makes the same Site Set work across different projects.

Multi-Site Setup Benefits

Here's where Site Sets really shine. Need the same design for multiple clients? Just create different site configurations:

Client A: config/sites/client-a/config.yaml

rootPageId: 10
base: 'https://client-a.com/'
dependencies:
  - my-theme
settings:
  website:
    logo: EXT:my_site_package/Resources/Public/Images/client-a-logo.svg
    colors:
      primary: '#ff6600'

Client B: config/sites/client-b/config.yaml

rootPageId: 20
base: 'https://client-b.com/'
dependencies:
  - my-theme
settings:
  website:
    logo: EXT:my_site_package/Resources/Public/Images/client-b-logo.svg
    colors:
      primary: '#009900'

Same Site Set, different branding. No code duplication.

Advanced PAGEVIEW Features

PAGEVIEW supports data processors just like FLUIDTEMPLATE. Add complex data preparation:

page.10 {
    dataProcessing {
        10 = TYPO3\CMS\Frontend\DataProcessing\MenuProcessor
        10 {
            levels = 2
            as = mainNavigation
        }
        
        20 = TYPO3\CMS\Frontend\DataProcessing\DatabaseQueryProcessor
        20 {
            table = tt_news
            pidInList = 15
            orderBy = datetime DESC
            max = 3
            as = latestNews
        }
    }
}

Use the processed data in your template:

<nav class="main-nav">
    <f:for each="{mainNavigation}" as="item">
        <f:link.page pageUid="{item.data.uid}" class="{f:if(condition: item.active, then: 'active')}">{item.title}</f:link.page>
    </f:for>
</nav>

<aside class="news-sidebar">
    <h3>Latest News</h3>
    <f:for each="{latestNews}" as="article">
        <article>
            <h4>{article.title}</h4>
            <time datetime="{article.datetime -> f:format.date(format: 'Y-m-d')}">{article.datetime -> f:format.date()}</time>
        </article>
    </f:for>
</aside>

Debugging and Development Tips

Enable debug output during development. Add this to your Site Set's TypoScript:

[applicationContext == "Development"]
config.debug = 1
page.10.settings.debugMode = 1
[END]

Use the TYPO3 admin panel to inspect PAGEVIEW rendering. Go to Admin Panel > Info and check “Display cObject times and SQL queries.”

Common Migration Pitfalls

Don't mix old and new approaches. Remove lib.parseFunc_RTE references when using PAGEVIEW. The new system handles RTE parsing automatically.

Site Set dependencies matter. List them in the right order. Core sets should come before custom ones:

dependencies:
  - typo3/fluid-styled-content  # Core first
  - typo3/seo                   # Core features
  - my-theme                    # Custom last

Settings cascade properly. Site configuration overrides Site Set settings, which override extension defaults. Use this hierarchy intentionally.

Performance Considerations

PAGEVIEW renders faster than traditional FLUIDTEMPLATE approaches. But don't add unnecessary data processors. Each processor runs on every page load.

Cache your complex calculations:

lib.expensiveCalculation = USER
lib.expensiveCalculation {
    userFunc = MyVendor\MyExtension\UserFunc\Calculator->process
    cache.lifetime = 3600
    cache.tags = pages
}

Site Sets don't impact frontend performance. They're processed during bootstrap, not on each request.

Testing Your Site Package

Create a simple test to verify your Site Set loads correctly:

<?php
// Tests/Functional/SiteSetTest.php
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;

class SiteSetTest extends FunctionalTestCase
{
    protected array $testExtensionsToLoad = [
        'my_site_package'
    ];

    public function testSiteSetIsLoadable(): void
    {
        $this->importCSVDataSet(__DIR__ . '/Fixtures/pages.csv');
        $this->setUpFrontendSite(1, [
            'dependencies' => ['my-theme']
        ]);
        
        $response = $this->executeFrontendSubRequest(
            new InternalRequest('https://example.com/')
        );
        
        $this->assertEquals(200, $response->getStatusCode());
        $this->assertStringContainsString('<title>', (string)$response->getBody());
    }
}

What's Next?

You now have a modern TYPO3 site package that uses both PAGEVIEW and Site Sets effectively. The combination creates cleaner code that's easier to maintain and deploy across multiple sites.

Consider adding:

  • Custom content elements using the new registration API
  • Advanced data processors for complex content scenarios
  • Asset building integration with Vite or Webpack
  • Automated deployment workflows that handle Site Set configurations

The v13 approach scales better than previous methods. Start with this foundation and add complexity only when needed.

No, PAGEVIEW is exclusive to TYPO3 v13 and later. For older versions, stick with FLUIDTEMPLATE.

No, but they reduce TypoScript complexity significantly. You still need TypoScript for page objects and lib definitions.

Create a Site Set configuration, move constants to settings, and update your site configuration to reference the new Site Set.

Yes, list multiple dependencies in your site configuration. They're processed in order.

Yes, Site Set configurations are cached during bootstrap. Clear system cache when changing config.yaml files.

Minimal changes required. PAGEVIEW uses the same Fluid syntax as FLUIDTEMPLATE.

Post a Comment

×

Got answer to the question you were looking for?