Drupal 11 Changes & Deprecations
When to Use
When upgrading to Drupal 11 or maintaining modules compatible with Drupal 11.x.
Decision: Migration Path
| Deprecated element | Replacement | Action required |
|---|---|---|
content_translation.admin.inc functions |
Functions moved to content_translation.module |
Update function calls (path changes, signatures same) |
t() global function (still works) |
$this->t() via StringTranslationTrait |
Refactor for best practices (not breaking) |
Pattern: content_translation.admin.inc Deprecation
Deprecated in: Drupal 11.4.0 Removed in: Drupal 12.0.0
Background:
- content_translation.admin.inc contained helper functions for field sync UI
- Functions moved to content_translation.module
- File deprecated, will be removed in Drupal 12
Affected function:
- content_translation_field_sync_widget()
Migration:
// OLD (deprecated)
include_once \Drupal::root() . '/core/modules/content_translation/content_translation.admin.inc';
$widget = content_translation_field_sync_widget($field);
// NEW (Drupal 11.4+)
// Function now in content_translation.module (auto-loaded)
$widget = content_translation_field_sync_widget($field);
If you directly included the file, remove the include_once:
// Remove this line
include_once \Drupal::root() . '/core/modules/content_translation/content_translation.admin.inc';
// Function still available
$widget = content_translation_field_sync_widget($field);
Most modules won't be affected — function auto-loaded from .module file.
Pattern: Best Practices Updates (Non-Breaking)
t() function — still works but discouraged in new code:
// OLD (still works, not deprecated)
$message = t('Hello, world!');
// NEW (best practice)
use Drupal\Core\StringTranslation\StringTranslationTrait;
class MyClass {
use StringTranslationTrait;
public function myMethod() {
$message = $this->t('Hello, world!');
}
}
Reason: $this->t() is testable, mockable, dependency-injectable.
Pattern: Checking for Drupal 11 Compatibility
Module compatibility:
# mymodule.info.yml
name: My Module
core_version_requirement: ^10 || ^11
Check for deprecated code:
# Use Drupal Check or PHPStan
composer require --dev mglaman/drupal-check
vendor/bin/drupal-check modules/custom/mymodule
# Or PHPStan with Drupal extension
composer require --dev phpstan/phpstan drupal/core-dev
vendor/bin/phpstan analyze modules/custom/mymodule
Known Issues & Changes
Twig 3.x (Drupal 11.x uses Twig 3): - Stricter syntax checking - Some deprecated Twig 2 patterns removed - Update custom Twig extensions if any
Symfony 6.4 / 7.x: - Drupal 11 uses newer Symfony components - Some Symfony APIs changed - Check custom services using Symfony components
jQuery updates: - Drupal 11 updates jQuery version - Some jQuery plugins may need updates - Test custom JavaScript libraries
No major translation system changes — core translation architecture stable between Drupal 10 and 11.
Common Mistakes
- Not testing after Drupal 11 upgrade → Even non-deprecated code may behave differently. Test all translation workflows
- Ignoring deprecation warnings → Drupal logs deprecation warnings. Monitor logs and fix before Drupal 12
- Not checking contrib module compatibility → TMGMT and other translation modules may need updates for Drupal 11
- Assuming all APIs unchanged → Some edge case APIs changed. Review change records at https://www.drupal.org/list-changes/drupal
See Also
- → Interface Translation — .po file management (unchanged)
- → Translating Custom Modules — best practices
- Reference: https://www.drupal.org/project/drupal/issues/3560560 (deprecated message fix)
- Reference: https://www.drupal.org/docs/understanding-drupal/how-drupal-11-is-made-and-what-is-included (Drupal 11 overview)