diff --git a/src/Symfony/Bundle/Resources/views/SwaggerUi/index.html.twig b/src/Symfony/Bundle/Resources/views/SwaggerUi/index.html.twig
index 7c026ff061..294b30a5dc 100644
--- a/src/Symfony/Bundle/Resources/views/SwaggerUi/index.html.twig
+++ b/src/Symfony/Bundle/Resources/views/SwaggerUi/index.html.twig
@@ -10,7 +10,7 @@
{% if title %}{{ title }} - {% endif %}API Platform
{% endblock %}
- {% set active_ui = app.request.query.get('ui', 'swagger_ui') %}
+ {% set active_ui = app.request.query.get('ui', reDocEnabled and not swaggerUiEnabled ? 're_doc' : 'swagger_ui') %}
{% set is_scalar = (scalarEnabled and not swaggerUiEnabled and not reDocEnabled) or (scalarEnabled and 'scalar' == active_ui) %}
{%- set csp_nonce_attr = cspNonce is defined and cspNonce is not null ? ' nonce="' ~ (cspNonce|e('html_attr')) ~ '"' : '' -%}
@@ -90,12 +90,19 @@
{% for format in formats|keys %}
{{ format }}
{% endfor %}
-
- Other API docs:
- {% if swaggerUiEnabled and active_ui != 'swagger_ui' %}Swagger UI{% endif %}
- {% if reDocEnabled and active_ui != 're_doc' %}ReDoc{% endif %}
- {% if scalarEnabled and active_ui != 'scalar' %}Scalar{% endif %}
- {% if graphiQlEnabled %}GraphiQL{% endif %}
+
+ {% set swaggerUiOption = swaggerUiEnabled and active_ui != 'swagger_ui' %}
+ {% set reDocOption = reDocEnabled and active_ui != 're_doc' %}
+ {% set scalarOption = scalarEnabled and active_ui != 'scalar' %}
+
+ {% if swaggerUiOption or reDocOption or scalarOption or graphiQlEnabled %}
+
+ Other API docs:
+ {% if swaggerUiOption %}Swagger UI{% endif %}
+ {% if reDocOption %}ReDoc{% endif %}
+ {% if scalarOption %}Scalar{% endif %}
+ {% if graphiQlEnabled %}GraphiQL{% endif %}
+ {% endif %}
@@ -105,7 +112,7 @@
{% if is_scalar %}
- {% elseif (reDocEnabled and not swaggerUiEnabled) or (reDocEnabled and 're_doc' == active_ui) %}
+ {% elseif (reDocEnabled and 're_doc' == active_ui) %}
{% else %}
diff --git a/tests/Functional/RedocOtherApiDocLinkTest.php b/tests/Functional/RedocOtherApiDocLinkTest.php
new file mode 100644
index 0000000000..3129427144
--- /dev/null
+++ b/tests/Functional/RedocOtherApiDocLinkTest.php
@@ -0,0 +1,69 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+declare(strict_types=1);
+
+namespace ApiPlatform\Tests\Functional;
+
+use ApiPlatform\Test\ApiTestCase;
+use Symfony\Component\Config\Loader\LoaderInterface;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+
+class RedocOtherApiDocLinkAppKernel extends \AppKernel
+{
+ public function getCacheDir(): string
+ {
+ return parent::getCacheDir().'/redoc_otherapidoc_link';
+ }
+
+ public function getLogDir(): string
+ {
+ return parent::getLogDir().'/redoc_otherapidoc_link';
+ }
+
+ protected function configureContainer(ContainerBuilder $c, LoaderInterface $loader): void
+ {
+ parent::configureContainer($c, $loader);
+
+ $loader->load(static function (ContainerBuilder $container): void {
+ $container->loadFromExtension('api_platform', [
+ 'enable_swagger_ui' => false,
+ 'enable_re_doc' => true,
+ 'enable_scalar' => false,
+ 'graphql' => ['enabled' => false],
+ ]);
+
+ // the fixtures decorate a GraphQL service that is not registered once GraphQL is off
+ if ($container->hasDefinition('app.graphql.type_converter')) {
+ $container->removeDefinition('app.graphql.type_converter');
+ }
+ });
+ }
+}
+
+final class RedocOtherApiDocLinkTest extends ApiTestCase
+{
+ protected static ?bool $alwaysBootKernel = true;
+
+ protected static function getKernelClass(): string
+ {
+ return RedocOtherApiDocLinkAppKernel::class;
+ }
+
+ public function testOtherApiDocsLinkAreHiddenWhenAllOptionsAreDisabled(): void
+ {
+ $client = self::createClient();
+ $client->request('GET', '/docs', ['headers' => ['Accept' => 'text/html']]);
+
+ $this->assertResponseIsSuccessful();
+ $this->assertStringNotContainsString('Other API docs:', $client->getResponse()->getContent());
+ }
+}
diff --git a/tests/Functional/SwaggerUiOtherApiDocLinkTest.php b/tests/Functional/SwaggerUiOtherApiDocLinkTest.php
new file mode 100644
index 0000000000..27b4d4c53c
--- /dev/null
+++ b/tests/Functional/SwaggerUiOtherApiDocLinkTest.php
@@ -0,0 +1,69 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+declare(strict_types=1);
+
+namespace ApiPlatform\Tests\Functional;
+
+use ApiPlatform\Test\ApiTestCase;
+use Symfony\Component\Config\Loader\LoaderInterface;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+
+class SwaggerUiOtherApiDocLinkAppKernel extends \AppKernel
+{
+ public function getCacheDir(): string
+ {
+ return parent::getCacheDir().'/swagger_otherapidoc_link';
+ }
+
+ public function getLogDir(): string
+ {
+ return parent::getLogDir().'/swagger_otherapidoc_link';
+ }
+
+ protected function configureContainer(ContainerBuilder $c, LoaderInterface $loader): void
+ {
+ parent::configureContainer($c, $loader);
+
+ $loader->load(static function (ContainerBuilder $container): void {
+ $container->loadFromExtension('api_platform', [
+ 'enable_swagger_ui' => true,
+ 'enable_re_doc' => false,
+ 'enable_scalar' => false,
+ 'graphql' => ['enabled' => false],
+ ]);
+
+ // the fixtures decorate a GraphQL service that is not registered once GraphQL is off
+ if ($container->hasDefinition('app.graphql.type_converter')) {
+ $container->removeDefinition('app.graphql.type_converter');
+ }
+ });
+ }
+}
+
+final class SwaggerUiOtherApiDocLinkTest extends ApiTestCase
+{
+ protected static ?bool $alwaysBootKernel = true;
+
+ protected static function getKernelClass(): string
+ {
+ return SwaggerUiOtherApiDocLinkAppKernel::class;
+ }
+
+ public function testOtherApiDocsLinkAreHiddenWhenAllOptionsAreDisabled(): void
+ {
+ $client = self::createClient();
+ $client->request('GET', '/docs', ['headers' => ['Accept' => 'text/html']]);
+
+ $this->assertResponseIsSuccessful();
+ $this->assertStringNotContainsString('Other API docs:', $client->getResponse()->getContent());
+ }
+}