typo3-seo

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

TYPO3 SEO Configuration

TYPO3 SEO配置

Compatibility: TYPO3 v13.x and v14.x (v14 preferred) All SEO configurations in this skill work on both v13 and v14.
TYPO3 API First: Always use TYPO3's built-in APIs, core features, and established conventions before creating custom implementations. Do not reinvent what TYPO3 already provides. Always verify that the APIs and methods you use exist and are not deprecated in your target TYPO3 version (v13 or v14) by checking the official TYPO3 documentation.
兼容性: TYPO3 v13.x 和 v14.x(推荐使用v14) 本文中所有SEO配置均可在v13和v14版本中生效。
TYPO3 API优先原则: 在实现自定义功能前,请优先使用TYPO3的内置API、核心功能及既定规范。不要重复开发TYPO3已提供的功能。请务必通过官方文档确认你所使用的API和方法在目标TYPO3版本(v13或v14)中存在且未被弃用。

1. Core SEO Extension Setup

1. 核心SEO扩展设置

Installation

安装

bash
ddev composer require typo3/cms-seo
ddev typo3 extension:activate seo
ddev typo3 cache:flush
bash
ddev composer require typo3/cms-seo
ddev typo3 extension:activate seo
ddev typo3 cache:flush

Page Properties SEO Tab

页面属性SEO标签页

After installation, pages have an "SEO" tab with:
  • seo_title
    - Override page title for search engines
  • description
    - Meta description
  • og_title
    ,
    og_description
    ,
    og_image
    - Open Graph
  • twitter_title
    ,
    twitter_description
    ,
    twitter_image
    - Twitter Cards
  • canonical_link
    - Canonical URL override
  • no_index
    ,
    no_follow
    - Robot directives
安装完成后,页面会新增一个「SEO」标签页,包含以下选项:
  • seo_title
    - 覆盖页面标题以适配搜索引擎
  • description
    - 元描述
  • og_title
    ,
    og_description
    ,
    og_image
    - OpenGraph相关设置
  • twitter_title
    ,
    twitter_description
    ,
    twitter_image
    - Twitter卡片相关设置
  • canonical_link
    - 规范URL覆盖
  • no_index
    ,
    no_follow
    - 搜索引擎机器人指令

2. Meta Tags Configuration

2. 元标签配置

TypoScript Setup (v13/v14)

TypoScript设置(v13/v14)

typoscript
page {
    meta {
        # Basic meta tags
        viewport = width=device-width, initial-scale=1
        robots = index,follow
        author = webconsulting
        
        # Open Graph (auto-filled by EXT:seo if page properties set)
        og:type = website
        og:site_name = {$site.name}
        og:locale = de_AT
        
        # Twitter Cards
        twitter:card = summary_large_image
        twitter:site = @webconsulting
    }
}
typoscript
page {
    meta {
        # Basic meta tags
        viewport = width=device-width, initial-scale=1
        robots = index,follow
        author = webconsulting
        
        # Open Graph (auto-filled by EXT:seo if page properties set)
        og:type = website
        og:site_name = {$site.name}
        og:locale = de_AT
        
        # Twitter Cards
        twitter:card = summary_large_image
        twitter:site = @webconsulting
    }
}

Dynamic Meta Description

动态元描述

typoscript
page.meta.description = TEXT
page.meta.description {
    # Fallback chain: page description > parent description > site description
    data = page:description // levelfield:-1,description,slide // {$site.description}
    htmlSpecialChars = 1
}
typoscript
page.meta.description = TEXT
page.meta.description {
    # Fallback chain: page description > parent description > site description
    data = page:description // levelfield:-1,description,slide // {$site.description}
    htmlSpecialChars = 1
}

Hreflang Tags (Multi-Language)

Hreflang标签(多语言站点)

EXT:seo automatically generates hreflang tags based on site configuration:
yaml
undefined
EXT:seo会根据站点配置自动生成hreflang标签:
yaml
undefined

config/sites/main/config.yaml

config/sites/main/config.yaml

languages:
  • languageId: 0 locale: de_AT hreflang: de-AT title: Deutsch
  • languageId: 1 locale: en_GB hreflang: en-GB title: English
undefined
languages:
  • languageId: 0 locale: de_AT hreflang: de-AT title: Deutsch
  • languageId: 1 locale: en_GB hreflang: en-GB title: English
undefined

3. XML Sitemap Configuration

3. XML站点地图配置

Basic Sitemap Setup

基础站点地图设置

yaml
undefined
yaml
undefined

config/sites/main/config.yaml

config/sites/main/config.yaml

base: 'https://example.com/' routeEnhancers: PageTypeSuffix: type: PageType map: sitemap.xml: 1533906435
undefined
base: 'https://example.com/' routeEnhancers: PageTypeSuffix: type: PageType map: sitemap.xml: 1533906435
undefined

TypoScript Sitemap Configuration (v13/v14)

TypoScript站点地图配置(v13/v14)

typoscript
plugin.tx_seo {
    config {
        xmlSitemap {
            sitemaps {
                # Pages sitemap (default)
                pages {
                    provider = TYPO3\CMS\Seo\XmlSitemap\PagesXmlSitemapDataProvider
                    config {
                        excludedDoktypes = 3,4,6,7,199,254,255
                        additionalWhere = no_index = 0 AND nav_hide = 0
                    }
                }
                
                # News sitemap (example for EXT:news)
                news {
                    provider = GeorgRinger\News\Seo\NewsXmlSitemapDataProvider
                    config {
                        table = tx_news_domain_model_news
                        sortField = datetime
                        lastModifiedField = tstamp
                        changeFreqField = sitemap_changefreq
                        priorityField = sitemap_priority
                        additionalWhere = {#hidden} = 0 AND {#deleted} = 0
                        pid = 123
                        url {
                            pageId = 45
                            fieldToParameterMap {
                                uid = tx_news_pi1[news]
                            }
                        }
                    }
                }
                
                # Products sitemap (custom extension)
                products {
                    provider = TYPO3\CMS\Seo\XmlSitemap\RecordsXmlSitemapDataProvider
                    config {
                        table = tx_shop_domain_model_product
                        sortField = title
                        lastModifiedField = tstamp
                        pid = 100
                        recursive = 2
                        url {
                            pageId = 50
                            fieldToParameterMap {
                                uid = tx_shop_pi1[product]
                            }
                            additionalGetParameters {
                                tx_shop_pi1.controller = Product
                                tx_shop_pi1.action = show
                            }
                        }
                    }
                }
            }
        }
    }
}
typoscript
plugin.tx_seo {
    config {
        xmlSitemap {
            sitemaps {
                # Pages sitemap (default)
                pages {
                    provider = TYPO3\CMS\Seo\XmlSitemap\PagesXmlSitemapDataProvider
                    config {
                        excludedDoktypes = 3,4,6,7,199,254,255
                        additionalWhere = no_index = 0 AND nav_hide = 0
                    }
                }
                
                # News sitemap (example for EXT:news)
                news {
                    provider = GeorgRinger\News\Seo\NewsXmlSitemapDataProvider
                    config {
                        table = tx_news_domain_model_news
                        sortField = datetime
                        lastModifiedField = tstamp
                        changeFreqField = sitemap_changefreq
                        priorityField = sitemap_priority
                        additionalWhere = {#hidden} = 0 AND {#deleted} = 0
                        pid = 123
                        url {
                            pageId = 45
                            fieldToParameterMap {
                                uid = tx_news_pi1[news]
                            }
                        }
                    }
                }
                
                # Products sitemap (custom extension)
                products {
                    provider = TYPO3\CMS\Seo\XmlSitemap\RecordsXmlSitemapDataProvider
                    config {
                        table = tx_shop_domain_model_product
                        sortField = title
                        lastModifiedField = tstamp
                        pid = 100
                        recursive = 2
                        url {
                            pageId = 50
                            fieldToParameterMap {
                                uid = tx_shop_pi1[product]
                            }
                            additionalGetParameters {
                                tx_shop_pi1.controller = Product
                                tx_shop_pi1.action = show
                            }
                        }
                    }
                }
            }
        }
    }
}

Sitemap Index

站点地图索引

Access sitemap at:
https://example.com/sitemap.xml
Individual sitemaps:
  • https://example.com/sitemap.xml?sitemap=pages
  • https://example.com/sitemap.xml?sitemap=news
访问地址:
https://example.com/sitemap.xml
独立站点地图:
  • https://example.com/sitemap.xml?sitemap=pages
  • https://example.com/sitemap.xml?sitemap=news

4. Robots.txt Configuration

4. Robots.txt配置

Static Robots.txt

静态Robots.txt

text
undefined
text
undefined

public/robots.txt

public/robots.txt

User-agent: * Allow: /
User-agent: * Allow: /

Disallow TYPO3 backend and system directories

Disallow TYPO3 backend and system directories

Disallow: /typo3/ Disallow: /typo3conf/ Disallow: /typo3temp/
Disallow: /typo3/ Disallow: /typo3conf/ Disallow: /typo3temp/

Sitemap location

Sitemap location

Dynamic Robots.txt via TypoScript

通过TypoScript生成动态Robots.txt

typoscript
undefined
typoscript
undefined

Generate robots.txt dynamically

Generate robots.txt dynamically

robotstxt = PAGE robotstxt { typeNum = 9999 config { disableAllHeaderCode = 1 additionalHeaders.10.header = Content-Type: text/plain; charset=utf-8 }
10 = TEXT
10.value (
User-agent: * Allow: / Disallow: /typo3/ Disallow: /typo3conf/ Disallow: /typo3temp/
Sitemap: {getEnv:TYPO3_SITE_URL}sitemap.xml ) }

Route enhancement:

```yaml
robotstxt = PAGE robotstxt { typeNum = 9999 config { disableAllHeaderCode = 1 additionalHeaders.10.header = Content-Type: text/plain; charset=utf-8 }
10 = TEXT
10.value (
User-agent: * Allow: / Disallow: /typo3/ Disallow: /typo3conf/ Disallow: /typo3temp/
Sitemap: {getEnv:TYPO3_SITE_URL}sitemap.xml ) }

路由增强配置:

```yaml

config/sites/main/config.yaml

config/sites/main/config.yaml

routeEnhancers: PageTypeSuffix: type: PageType map: robots.txt: 9999
undefined
routeEnhancers: PageTypeSuffix: type: PageType map: robots.txt: 9999
undefined

5. Canonical URLs

5. 规范URL配置

Automatic Canonicals

自动生成规范URL

EXT:seo generates canonical tags automatically. Configure in site:
yaml
undefined
EXT:seo会自动生成规范标签。可在站点配置中设置:
yaml
undefined

config/sites/main/config.yaml

config/sites/main/config.yaml

base: 'https://example.com/' baseVariants:
undefined
base: 'https://example.com/' baseVariants:
undefined

Manual Canonical Override

手动覆盖规范URL

In page properties SEO tab, set "Canonical URL" field.
Via TypoScript:
typoscript
page.headerData.100 = TEXT
page.headerData.100 {
    value = <link rel="canonical" href="https://example.com/specific-page" />
}
在页面属性的SEO标签页中,设置「规范URL」字段。
也可通过TypoScript设置:
typoscript
page.headerData.100 = TEXT
page.headerData.100 {
    value = <link rel="canonical" href="https://example.com/specific-page" />
}

6. Structured Data (JSON-LD)

6. 结构化数据(JSON-LD)

Organization Schema

组织架构Schema

typoscript
page.headerData.200 = TEXT
page.headerData.200.value (
<script type="application/ld+json">
{
    "@context": "https://schema.org",
    "@type": "Organization",
    "name": "webconsulting",
    "url": "https://webconsulting.at",
    "logo": "https://webconsulting.at/logo.png",
    "sameAs": [
        "https://www.linkedin.com/company/webconsulting",
        "https://github.com/webconsulting"
    ],
    "contactPoint": {
        "@type": "ContactPoint",
        "telephone": "+43-1-234567",
        "contactType": "customer service"
    }
}
</script>
)
typoscript
page.headerData.200 = TEXT
page.headerData.200.value (
<script type="application/ld+json">
{
    "@context": "https://schema.org",
    "@type": "Organization",
    "name": "webconsulting",
    "url": "https://webconsulting.at",
    "logo": "https://webconsulting.at/logo.png",
    "sameAs": [
        "https://www.linkedin.com/company/webconsulting",
        "https://github.com/webconsulting"
    ],
    "contactPoint": {
        "@type": "ContactPoint",
        "telephone": "+43-1-234567",
        "contactType": "customer service"
    }
}
</script>
)

Breadcrumb Schema (Dynamic)

动态面包屑Schema

typoscript
lib.breadcrumbSchema = COA
lib.breadcrumbSchema {
    10 = TEXT
    10.value = <script type="application/ld+json">{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[
    
    20 = HMENU
    20 {
        special = rootline
        special.range = 0|-1
        1 = TMENU
        1 {
            NO = 1
            NO {
                doNotLinkIt = 1
                stdWrap.cObject = COA
                stdWrap.cObject {
                    10 = TEXT
                    10.value = {"@type":"ListItem","position":
                    20 = TEXT
                    20.data = register:count_HMENU_MENUOBJ
                    30 = TEXT
                    30.value = ,"name":"
                    40 = TEXT
                    40.field = nav_title // title
                    40.htmlSpecialChars = 1
                    50 = TEXT
                    50.value = ","item":"
                    60 = TEXT
                    60.typolink.parameter.field = uid
                    60.typolink.returnLast = url
                    60.typolink.forceAbsoluteUrl = 1
                    70 = TEXT
                    70.value = "},
                }
            }
        }
    }
    
    30 = TEXT
    30.value = ]}</script>
    30.replacement {
        10.search = ,]}
        10.replace = ]}
    }
}

page.headerData.300 < lib.breadcrumbSchema
typoscript
lib.breadcrumbSchema = COA
lib.breadcrumbSchema {
    10 = TEXT
    10.value = <script type="application/ld+json">{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[
    
    20 = HMENU
    20 {
        special = rootline
        special.range = 0|-1
        1 = TMENU
        1 {
            NO = 1
            NO {
                doNotLinkIt = 1
                stdWrap.cObject = COA
                stdWrap.cObject {
                    10 = TEXT
                    10.value = {"@type":"ListItem","position":
                    20 = TEXT
                    20.data = register:count_HMENU_MENUOBJ
                    30 = TEXT
                    30.value = ,"name":"
                    40 = TEXT
                    40.field = nav_title // title
                    40.htmlSpecialChars = 1
                    50 = TEXT
                    50.value = ","item":"
                    60 = TEXT
                    60.typolink.parameter.field = uid
                    60.typolink.returnLast = url
                    60.typolink.forceAbsoluteUrl = 1
                    70 = TEXT
                    70.value = "},
                }
            }
        }
    }
    
    30 = TEXT
    30.value = ]}</script>
    30.replacement {
        10.search = ,]}
        10.replace = ]}
    }
}

page.headerData.300 < lib.breadcrumbSchema

Advanced Structured Data with EXT:schema

使用EXT:schema实现高级结构化数据

bash
undefined
bash
undefined

Install schema extension for advanced structured data

Install schema extension for advanced structured data

ddev composer require brotkrueml/schema

```php
<?php
// In a PSR-14 event listener
use Brotkrueml\Schema\Type\TypeFactory;
use Brotkrueml\Schema\Manager\SchemaManager;

#[AsEventListener]
final class AddSchemaListener
{
    public function __construct(
        private readonly TypeFactory $typeFactory,
        private readonly SchemaManager $schemaManager,
    ) {}

    public function __invoke(SomeEvent $event): void
    {
        $organization = $this->typeFactory->create('Organization')
            ->setProperty('name', 'My Company')
            ->setProperty('url', 'https://example.com');
        
        $this->schemaManager->addType($organization);
    }
}
ddev composer require brotkrueml/schema

```php
<?php
// In a PSR-14 event listener
use Brotkrueml\Schema\Type\TypeFactory;
use Brotkrueml\Schema\Manager\SchemaManager;

#[AsEventListener]
final class AddSchemaListener
{
    public function __construct(
        private readonly TypeFactory $typeFactory,
        private readonly SchemaManager $schemaManager,
    ) {}

    public function __invoke(SomeEvent $event): void
    {
        $organization = $this->typeFactory->create('Organization')
            ->setProperty('name', 'My Company')
            ->setProperty('url', 'https://example.com');
        
        $this->schemaManager->addType($organization);
    }
}

7. Performance SEO

7. 性能优化(SEO相关)

Core Web Vitals Optimization

Core Web Vitals优化

typoscript
undefined
typoscript
undefined

Preload critical resources

Preload critical resources

page.headerData.50 = TEXT page.headerData.50.value (
<link rel="preload" href="/typo3conf/ext/site_package/Resources/Public/Fonts/raleway.woff2" as="font" type="font/woff2" crossorigin> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="dns-prefetch" href="https://www.google-analytics.com"> )
page.headerData.50 = TEXT page.headerData.50.value (
<link rel="preload" href="/typo3conf/ext/site_package/Resources/Public/Fonts/raleway.woff2" as="font" type="font/woff2" crossorigin> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="dns-prefetch" href="https://www.google-analytics.com"> )

Lazy load images (built-in v13/v14)

Lazy load images (built-in v13/v14)

lib.contentElement { settings { media { lazyLoading = lazy } } }
undefined
lib.contentElement { settings { media { lazyLoading = lazy } } }
undefined

Image Optimization (v13/v14)

图片优化(v13/v14)

php
// config/system/additional.php
$GLOBALS['TYPO3_CONF_VARS']['GFX']['processor_allowUpscaling'] = false;

// WebP is automatically generated in v13/v14 when supported
typoscript
undefined
php
// config/system/additional.php
$GLOBALS['TYPO3_CONF_VARS']['GFX']['processor_allowUpscaling'] = false;

// WebP is automatically generated in v13/v14 when supported
typoscript
undefined

Responsive images

Responsive images

tt_content.image.settings.responsive_image_rendering = 1
undefined
tt_content.image.settings.responsive_image_rendering = 1
undefined

8. SEO Checklist

8. SEO检查清单

Page Level

页面层级

  • Unique
    <title>
    with primary keyword (50-60 chars)
  • Meta description with call-to-action (150-160 chars)
  • Single H1 per page containing primary keyword
  • Structured heading hierarchy (H1 > H2 > H3)
  • Alt text on all images
  • Internal links with descriptive anchor text
  • External links with
    rel="noopener"
    on
    target="_blank"
  • 包含主关键词的唯一
    <title>
    标签(50-60字符)
  • 带行动号召的元描述(150-160字符)
  • 每页仅一个包含主关键词的H1标签
  • 结构化标题层级(H1 > H2 > H3)
  • 所有图片添加替代文本
  • 使用描述性锚文本的内部链接
  • 新窗口打开的外部链接添加
    rel="noopener"
    属性

Technical

技术层级

  • XML sitemap submitted to Search Console
  • robots.txt properly configured
  • Canonical tags present
  • hreflang tags for multi-language
  • HTTPS enforced
  • Mobile-friendly (responsive)
  • Page speed < 3 seconds
  • Core Web Vitals passing
  • XML站点地图已提交至Search Console
  • Robots.txt配置正确
  • 存在规范URL标签
  • 多语言站点配置hreflang标签
  • 强制使用HTTPS
  • 适配移动端(响应式设计)
  • 页面加载时间小于3秒
  • Core Web Vitals达标

Content

内容层级

  • Unique content per page
  • Keywords naturally integrated
  • Fresh, regularly updated content
  • Structured data where applicable
  • 每页内容唯一
  • 关键词自然融入内容
  • 内容新鲜且定期更新
  • 合理使用结构化数据

9. SEO Extensions (v13/v14 Compatible)

9. 兼容v13/v14的SEO扩展

Recommended Extensions

推荐扩展

ExtensionPurposev13/v14 Support
typo3/cms-seo
Core SEO functionality
yoast-seo-for-typo3/yoast_seo
Content analysis, readability
brotkrueml/schema
Advanced structured data
b13/seo_basics
Additional SEO tools
扩展用途v13/v14支持
typo3/cms-seo
核心SEO功能
yoast-seo-for-typo3/yoast_seo
内容分析、可读性评分
brotkrueml/schema
高级结构化数据实现
b13/seo_basics
额外SEO工具

Yoast SEO Integration

Yoast SEO集成

bash
ddev composer require yoast-seo-for-typo3/yoast_seo
ddev typo3 extension:activate yoast_seo
Features:
  • Real-time content analysis
  • Readability scoring
  • Focus keyword optimization
  • Social preview
bash
ddev composer require yoast-seo-for-typo3/yoast_seo
ddev typo3 extension:activate yoast_seo
功能:
  • 实时内容分析
  • 可读性评分
  • 目标关键词优化
  • 社交预览

Schema Extension

Schema扩展

bash
ddev composer require brotkrueml/schema
ddev typo3 extension:activate schema
Features:
  • Type-safe schema.org implementation
  • WebPage, Organization, Article types
  • Event and Product schemas
bash
ddev composer require brotkrueml/schema
ddev typo3 extension:activate schema
功能:
  • 类型安全的schema.org实现
  • 支持WebPage、Organization、Article类型
  • 支持Event和Product schema

10. Monitoring & Analytics

10. 监控与分析

Google Search Console Integration

Google Search Console集成

  1. Verify domain ownership
  2. Submit sitemap:
    https://example.com/sitemap.xml
  3. Monitor crawl errors
  4. Check Core Web Vitals
  1. 验证域名所有权
  2. 提交站点地图:
    https://example.com/sitemap.xml
  3. 监控抓取错误
  4. 检查Core Web Vitals数据

Analytics Setup (GDPR Compliant)

合规GDPR的分析工具设置

typoscript
undefined
typoscript
undefined

Conditional Google Analytics (with consent)

Conditional Google Analytics (with consent)

[{$plugin.tx_cookie.googleAnalyticsConsent} == 1] page.headerData.1000 = TEXT page.headerData.1000.value (
<!-- Google Analytics --> <script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXX"></script> <script> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-XXXXXXXX', { 'anonymize_ip': true }); </script>
) [END]

---
[{$plugin.tx_cookie.googleAnalyticsConsent} == 1] page.headerData.1000 = TEXT page.headerData.1000.value (
<!-- Google Analytics --> <script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXX"></script> <script> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-XXXXXXXX', { 'anonymize_ip': true }); </script>
) [END]

---

Credits & Attribution

致谢与归属

Thanks to Netresearch DTT GmbH for their contributions to the TYPO3 community.
感谢Netresearch DTT GmbH为TYPO3社区做出的贡献。