Generating URLs with fromUri and the language prefix, base vs internal What is the recommended way to generate non-route URLs that include the language prefix?

Context: In CiviCRM, an open source third-party project that integrates with Drupal, we have a function that generates internal URLs (a wrapper over the CMS-specific function).

Since not all URLs referenced have a proper route, so far fromUri has given the best results (rather than fromRoute).

However, the URLs generated by fromUri do not seem to include the language prefix for multi-lingual configurations when using base as the prefix. The language prefix is included with internal, but if I understand correctly, internal should only be used for user-specified links, such as a link field.

Example on a site that has English and French, with French being the default language:

print \Drupal\Core\Url::fromUri("base:/admin")-&gt;toString() . "\n";
print \Drupal\Core\Url::fromUri("internal:/admin")-&gt;toString() . "\n";


$ drush scr test.php
/civicrm/dashboard?reset=1
/fr/civicrm/dashboard?reset=1


I also tried passing in the $language object, but the behaviour is the same:

$language = \Drupal::languageManager()-&gt;getCurrentLanguage();

print \Drupal\Core\Url::fromUri("base:/admin", [
  'language' =&gt; $language,
])-&gt;toString() . "\n";


Related question: Generating arbitrary internal URLs
Drupa8 - as a Symfony application - abstracts paths with routes. So paths may change, the route stays.
So the cited "The internal: scheme should be avoided except when processing actual user input that may or may not correspond to a Drupal route." means: If you can, use a route.
If you can not use routes, the right prefix for routed paths is internal:.
In contrast, base: was introduced for use cases like README.txt which is unknown to the symfony router and served directly by the web server.


You can find background in these issues, and help improve the docs:


Remove the base: scheme in favour of user-path:/internal: [#2422995] which concluded that we still need the base scheme
Evaluate and document each use of base: in core [#2417827] which then was started to at least document usages of the base scheme
Url::fromUri DocBlock does not mention base: and internal: custom schemes [#2877023] which is about improving the docs