---
title: "Reusable site sets"
manual: "TYPO3 Explained"
version: "main"
permalink: "https://docs.typo3.org/permalink/t3coreapi:site-sets-examples@main"
source: "ApiOverview/SiteHandling/SiteSets/ReusableSets.rst"
modified: "2026-09-14T11:10:56+00:00"
---

# Reusable site sets

A site package usually provides one set that configures a specific project. A
reusable extension can provide one base set and additional sets for optional
features. Both use the same file conventions and dependency mechanism.

The [Site sets](https://docs.typo3.org/permalink/t3coreapi:site-sets@main) chapter provides the quickstart and file reference. This
article builds on those mechanics and focuses on design decisions using complete
extension examples.

The distinction is about responsibility. A reusable extension owns the
configuration contract for its feature, including setting definitions and safe
defaults. A site package decides how those features are combined for a project
and which defaults should be overridden.

**Table of contents**

-   [Providing a set in a site package](https://docs.typo3.org/permalink/t3coreapi:providing-a-set-in-a-site-package@main)
-   [Providing sets in a reusable extension](https://docs.typo3.org/permalink/t3coreapi:providing-sets-in-a-reusable-extension@main)
-   [Choosing set boundaries](https://docs.typo3.org/permalink/t3coreapi:choosing-set-boundaries@main)

## Providing a set in a site package

Use a site-package set to combine project dependencies, TypoScript and setting
overrides.

Think of this set as the integration layer of the project. Instead of asking an
integrator to select several extension sets, include them as dependencies of
the site-package set. The site then activates one clearly named set and receives
the complete project configuration.

You can see an example of using a set within a site package in the extension
[t3docs/site-package (source on GitHub)](https://github.com/TYPO3-Documentation/TYPO3CMS-Tutorial-SitePackage-Code).

The site package example extension has the following file structure:

-   Configuration
    -   Sets
        -   MySitePackage
            -   config.yaml
            -   constants.typoscript
            -   page.tsconfig
            -   route-enhancers.yaml
            -   settings.yaml
            -   setup.typoscript
        -   ...
-   Resources
    -   ...
-   [`composer.json`](../../../ExtensionArchitecture/FileStructure/ComposerJson.md#file-extension-composer-json)
-   ...

### Define the dependency on EXT:fluid_styled_content

As the example site package contains only one site set, the set has the same
name as the Composer package.

Matching both names is a convention, not a technical requirement. It makes the
main set easy to discover and communicates that it is the default integration
offered by the package.

The site package depends on
[EXT:fluid_styled_content](https://docs.typo3.org/c/typo3/cms-fluid-styled-content/main/en-us/Index.html#start).
Therefore, the two sets provided by that system extension are included as
dependencies:

**EXT:site_package/Configuration/Sets/SitePackage/config.yaml**

```yaml
name: t3docs/site-package
label: 'Site Package'
dependencies:
  - typo3/fluid-styled-content
  - typo3/fluid-styled-content-css

```

Find all available sets with the console command
[bin/typo3 site:sets:list](https://docs.typo3.org/permalink/t3coreapi:site-sets-cli@main).

### Define an optional dependency on EXT:form

Optional dependencies work similarly to `suggest` in `composer.json`
(see [composer.json properties](https://docs.typo3.org/permalink/t3coreapi:ext-composer-json-properties@main)). An
optional dependency is loaded only when the referenced site set is available.
If it is unavailable, TYPO3 skips it without reporting an error.

In this example, the `typo3/form` set is loaded when it is available:

**EXT:site_package/Configuration/Sets/SitePackage/config.yaml**

```yaml
name: t3docs/site-package
label: 'Site Package with optional dependency'
dependencies:
  - typo3/fluid-styled-content
  - typo3/fluid-styled-content-css
optionalDependencies:
  - typo3/form

```

> [!TIP]
> **Hint**
>
> If you include optional dependencies, ensure that all other code, such as
> PHP and Fluid, also operates gracefully without them. List the extension
> in the Composer `suggest` key where appropriate.

### Use the site set as a site dependency

After the example site package is installed, include the site set in the site
configuration:

**config/sites/\<some_site>/config.yaml | typo3conf/sites/\<some_site>/config.yaml**

```yaml
base: 'https://site-package.ddev.site'
dependencies:
  - t3docs/site-package
rootPageId: 1

```

The site configuration remains responsible for enabling the set. Installing
the site package alone does not change an existing site.

### Load TypoScript via the site package's set

The example site package loads its TypoScript by placing
`constants.typoscript` and `setup.typoscript` in the set directory.
These files use `@import` statements to import local TypoScript
files from `Configuration/Sets/SitePackage/TypoScript`:

**EXT:site_package/Configuration/Sets/SitePackage/setup.typoscript**

```typoscript
@import './TypoScript/*.typoscript'
@import './TypoScript/Navigation/*.typoscript'

```

TypoScript from dependencies is included by the dependent sets, not by
TypoScript imports.

### Override default settings

In this example,
[`EXT:site_package/Configuration/Sets/SitePackage/settings.yaml`](../../../ExtensionArchitecture/FileStructure/Configuration/Sets/Index.md#file-set-settings-yaml) overrides
default settings from
[EXT:fluid_styled_content](https://docs.typo3.org/c/typo3/cms-fluid-styled-content/main/en-us/Index.html#start):

**EXT:site_package/Configuration/Sets/SitePackage/settings.yaml**

```yaml
styles.templates.layoutRootPath: EXT:my_site_package/Resources/Private/ContentElements/Layouts
styles.templates.partialRootPath: EXT:my_site_package/Resources/Private/ContentElements/Partials
styles.templates.templateRootPath: EXT:my_site_package/Resources/Private/ContentElements/Templates
styles.content.textmedia.maxW: 1200
styles.content.textmedia.maxWInText: 600
styles.content.textmedia.linkWraplightboxEnabled: true
styles.content.textmedia.lightboxCssClass: lightbox

```

These values are project presets. The site package does not redefine the
settings because their definitions and validation rules belong to
`typo3/fluid-styled-content`. Individual sites can still override the presets
in their own `settings.yaml`.

## Providing sets in a reusable extension

Use multiple sets when an extension provides reusable configuration or offers
features that integrators can activate separately.

Keep the base set focused on configuration required by every use of the
extension. Put optional presentation, feeds or integrations into additional
sets. This lets integrators choose a small dependency instead of loading every
feature provided by the extension.

Extensions other than site packages can also provide site sets. Sites or
other sets can depend on them to load their TypoScript and settings.

The example extension [`t3docs/blog-example`](https://packagist.org/packages/t3docs/blog-example) offers one main site set
and several sets for specific use cases. It has the following file structure:

-   Classes
    -   ...
-   Configuration
    -   Sets
        -   BlogExample
            -   config.yaml
            -   constants.typoscript
            -   page.tsconfig
            -   setup.typoscript
        -   DefaultStyles
            -   config.yaml
            -   setup.typoscript
        -   RssFeed
            -   config.yaml
            -   constants.typoscript
            -   setup.typoscript
        -   ...
-   Resources
    -   ...
-   composer.json
-   ...

### Separate functionality into multiple site sets

The main site set of the extension has the same name as the Composer package:

**EXT:blog_example/Configuration/Sets/BlogExample/config.yaml**

```yaml
name: t3docs/blog-example
label: Blog example set

```

The other two sets require this set and therefore declare it as a dependency:

**EXT:blog_example/Configuration/Sets/DefaultStyles/config.yaml**

```yaml
name: t3docs/blog-example-styles
label: Blog example default styles
dependencies:
  - t3docs/blog-example

```

**EXT:blog_example/Configuration/Sets/RssFeed/config.yaml**

```yaml
name: t3docs/blog-example-rss
label: Blog example RSS feed
dependencies:
  - t3docs/blog-example

```

The additional site sets provide TypoScript that depends on the base site set.
They do not use `@include` statements for the base TypoScript. The
declared dependency determines the loading order.

Because each feature set depends on the base set, consumers do not need to
repeat that dependency in their site package. TYPO3 follows the graph,
deduplicates the base set and loads it before the selected feature.

## Choosing set boundaries

A set should represent a configuration unit that makes sense to enable as a
whole. Keep configuration together when its parts always depend on each other.
Split it when an integrator may reasonably want one feature without another.

As a practical guideline:

-   keep a setting definition in the set that owns the corresponding feature;
-   keep project-specific values in the site-package set;
-   express relationships through set dependencies instead of duplicating
    imports; and
-   hide a set only when it is a technical building block that should normally
    be pulled in by another set.
