diff --git a/Render/Html/GetNelmioAsset.php b/Render/Html/GetNelmioAsset.php
index 8767682..38e85a6 100644
--- a/Render/Html/GetNelmioAsset.php
+++ b/Render/Html/GetNelmioAsset.php
@@ -12,30 +12,82 @@
 namespace Nelmio\ApiDocBundle\Render\Html;
 
 use Symfony\Bridge\Twig\Extension\AssetExtension;
+use Twig\TwigFunction;
 
 class GetNelmioAsset
 {
     private $assetExtension;
-    private $defaultAssetsMode;
+    private $resourcesDir;
+    private $cdnUrl;
+    private $assetsMode = AssetsMode::BUNDLE;
 
-    public function __construct(AssetExtension $assetExtension, $defaultAssetsMode)
+    public function __construct(AssetExtension $assetExtension)
     {
         $this->assetExtension = $assetExtension;
-        $this->defaultAssetsMode = $defaultAssetsMode;
+        $this->cdnUrl = 'https://cdn.jsdelivr.net/gh/nelmio/NelmioApiDocBundle/Resources/public';
+        $this->resourcesDir = __DIR__.'/../../Resources/public';
     }
 
-    public function __invoke($asset, $forcedMode = null)
+    public function toTwigFunction($assetsMode): TwigFunction
     {
-        $mode = $forcedMode ?: $this->defaultAssetsMode;
-        if (AssetsMode::CDN === $mode) {
-            return sprintf(
-                'https://cdn.jsdelivr.net/gh/nelmio/NelmioApiDocBundle@4.1/Resources/public/%s',
-                $asset
-            );
-        } elseif (AssetsMode::OFFLINE === $mode) {
-            return file_get_contents(__DIR__.sprintf('/../../Resources/public/%s', $asset));
+        $this->assetsMode = $assetsMode;
+
+        return new TwigFunction('nelmioAsset', $this, ['is_safe' => ['html']]);
+    }
+
+    public function __invoke($asset)
+    {
+        [$extension, $mode] = $this->getExtension($asset);
+        [$resource, $isInline] = $this->getResource($asset, $mode);
+        if ('js' == $extension) {
+            return $this->renderJavascript($resource, $isInline);
+        } elseif ('css' == $extension) {
+            return $this->renderCss($resource, $isInline);
         } else {
-            return $this->assetExtension->getAssetUrl(sprintf('bundles/nelmioapidoc/%s', $asset));
+            return $resource;
+        }
+    }
+
+    private function getExtension($asset)
+    {
+        $extension = mb_substr($asset, -3, 3, 'utf-8');
+        if ('.js' === $extension) {
+            return ['js', $this->assetsMode];
+        } elseif ('png' === $extension) {
+            return ['png', AssetsMode::OFFLINE == $this->assetsMode ? AssetsMode::CDN : $this->assetsMode];
+        } else {
+            return ['css', $this->assetsMode];
+        }
+    }
+
+    private function getResource($asset, $mode)
+    {
+        if (filter_var($asset, FILTER_VALIDATE_URL)) {
+            return [$asset, false];
+        } elseif (AssetsMode::OFFLINE === $mode) {
+            return [file_get_contents($this->resourcesDir.'/'.$asset), true];
+        } elseif (AssetsMode::CDN === $mode) {
+            return [$this->cdnUrl.'/'.$asset, false];
+        } else {
+            return [$this->assetExtension->getAssetUrl(sprintf('bundles/nelmioapidoc/%s', $asset)), false];
+        }
+    }
+
+    private function renderJavascript(string $script, bool $isInline)
+    {
+        if ($isInline) {
+            return sprintf('<script>%s</script>', $script);
+        } else {
+            return sprintf('<script src="%s"></script>', $script);
+        }
+    }
+
+    private function renderCss(string $stylesheet, bool $isInline)
+    {
+        if ($isInline) {
+            return sprintf('<style>%s</style>', $stylesheet);
+        } else {
+            return sprintf('<link rel="stylesheet" href="%s">', $stylesheet);
         }
     }
 }
diff --git a/Render/Html/HtmlOpenApiRenderer.php b/Render/Html/HtmlOpenApiRenderer.php
index 5bb8645..bedf14e 100644
--- a/Render/Html/HtmlOpenApiRenderer.php
+++ b/Render/Html/HtmlOpenApiRenderer.php
@@ -16,28 +16,23 @@ use Nelmio\ApiDocBundle\Render\OpenApiRenderer;
 use Nelmio\ApiDocBundle\Render\RenderOpenApi;
 use OpenApi\Annotations\OpenApi;
 use OpenApi\Annotations\Server;
-use Symfony\Bridge\Twig\Extension\AssetExtension;
 use Twig\Environment;
-use Twig\TwigFunction;
 
 class HtmlOpenApiRenderer implements OpenApiRenderer
 {
-    /**
-     * @var Environment|\Twig_Environment
-     */
+    /** @var Environment|\Twig_Environment */
     private $twig;
-    /**
-     * @var AssetExtension
-     */
-    private $assetExtension;
 
-    public function __construct($twig, AssetExtension $assetExtension)
+    /** @var GetNelmioAsset */
+    private $getNelmioAsset;
+
+    public function __construct($twig, GetNelmioAsset $getNelmioAsset)
     {
         if (!$twig instanceof \Twig_Environment && !$twig instanceof Environment) {
             throw new InvalidArgumentException(sprintf('Providing an instance of "%s" as twig is not supported.', get_class($twig)));
         }
         $this->twig = $twig;
-        $this->assetExtension = $assetExtension;
+        $this->getNelmioAsset = $getNelmioAsset;
     }
 
     public function getFormat(): string
@@ -53,12 +48,7 @@ class HtmlOpenApiRenderer implements OpenApiRenderer
             'swagger_ui_config' => [],
         ];
 
-        $this->twig->addFunction(
-            new TwigFunction(
-                'nelmioAsset',
-                new GetNelmioAsset($this->assetExtension, $options['assets_mode'])
-            )
-        );
+        $this->twig->addFunction($this->getNelmioAsset->toTwigFunction($options['assets_mode']));
 
         return $this->twig->render(
             '@NelmioApiDoc/SwaggerUi/index.html.twig',
diff --git a/Resources/config/services.xml b/Resources/config/services.xml
index e0127ae..d125a10 100644
--- a/Resources/config/services.xml
+++ b/Resources/config/services.xml
@@ -33,6 +33,9 @@
         </service>
         <service id="nelmio_api_doc.render_docs.html" class="Nelmio\ApiDocBundle\Render\Html\HtmlOpenApiRenderer" public="false">
             <argument type="service" id="twig" />
+            <argument type="service" id="nelmio_api_doc.render_docs.html.asset" />
+        </service>
+        <service id="nelmio_api_doc.render_docs.html.asset" class="Nelmio\ApiDocBundle\Render\Html\GetNelmioAsset" public="false">
             <argument type="service" id="twig.extension.assets" />
         </service>
         <service id="nelmio_api_doc.render_docs.json" class="Nelmio\ApiDocBundle\Render\Json\JsonOpenApiRenderer" public="false">
diff --git a/Resources/views/SwaggerUi/index.html.twig b/Resources/views/SwaggerUi/index.html.twig
index 0db7f8b..a1b3129 100644
--- a/Resources/views/SwaggerUi/index.html.twig
+++ b/Resources/views/SwaggerUi/index.html.twig
@@ -14,13 +14,8 @@ file that was distributed with this source code. #}
     <title>{% block title %}{{ swagger_data.spec.info.title }}{% endblock title %}</title>
 
     {% block stylesheets %}
-        {% if assets_mode == 'offline' %}
-        <style>{{ nelmioAsset('swagger-ui/swagger-ui.css')|raw }}</style>
-        <style>{{ nelmioAsset('style.css')|raw }}</style>
-        {% else %}
-        <link rel="stylesheet" href="{{ nelmioAsset('swagger-ui/swagger-ui.css') }}">
-        <link rel="stylesheet" href="{{ nelmioAsset('style.css.css') }}">
-        {% endif %}
+        {{ nelmioAsset('swagger-ui/swagger-ui.css') }}
+        {{ nelmioAsset('style.css') }}
     {% endblock stylesheets %}
 
     {% block swagger_data %}
@@ -59,11 +54,7 @@ file that was distributed with this source code. #}
     <header>
         {% block header %}
             <a id="logo" href="https://github.com/nelmio/NelmioApiDocBundle">
-                {% if assets_mode in ['offline', 'cdn'] %}
-                <img src="{{ nelmioAsset('logo.png', 'cdn') }}" alt="NelmioApiDocBundle">
-                {% else %}
                 <img src="{{ nelmioAsset('logo.png') }}" alt="NelmioApiDocBundle">
-                {% endif %}
             </a>
         {% endblock header %}
     </header>
@@ -73,20 +64,11 @@ file that was distributed with this source code. #}
     {% endblock %}
 
     {% block javascripts %}
-        {% if assets_mode == 'offline' %}
-        <script>{{ nelmioAsset('swagger-ui/swagger-ui-bundle.js')|raw }}</script>
-        <script>{{ nelmioAsset('swagger-ui/swagger-ui-standalone-preset.js')|raw }}</script>
-        {% else %}
-        <script src="{{ nelmioAsset('swagger-ui/swagger-ui-bundle.js') }}"></script>
-        <script src="{{ nelmioAsset('swagger-ui/swagger-ui-standalone-preset.js') }}"></script>
-        {% endif %}
+        {{ nelmioAsset('swagger-ui/swagger-ui-bundle.js') }}
+        {{ nelmioAsset('swagger-ui/swagger-ui-standalone-preset.js') }}
     {% endblock javascripts %}
 
-    {% if assets_mode == 'offline' %}
-    <script>{{ nelmioAsset('init-swagger-ui.js')|raw }}</script>
-    {% else %}
-    <script src="{{ nelmioAsset('init-swagger-ui.js') }}"></script>
-    {% endif %}
+    {{ nelmioAsset('init-swagger-ui.js') }}
 
     {% block swagger_initialization %}
         <script type="text/javascript">
diff --git a/Tests/Render/Html/GetNelmioAssetTest.php b/Tests/Render/Html/GetNelmioAssetTest.php
new file mode 100644
index 0000000..2077a11
--- /dev/null
+++ b/Tests/Render/Html/GetNelmioAssetTest.php
@@ -0,0 +1,112 @@
+<?php
+
+/*
+ * This file is part of the NelmioApiDocBundle package.
+ *
+ * (c) Nelmio
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Nelmio\ApiDocBundle\Tests\Render\Html;
+
+use Nelmio\ApiDocBundle\Render\Html\AssetsMode;
+use Nelmio\ApiDocBundle\Render\Html\GetNelmioAsset;
+use Nelmio\ApiDocBundle\Tests\Functional\WebTestCase;
+
+class GetNelmioAssetTest extends WebTestCase
+{
+    /** @dataProvider provideAsset */
+    public function test($mode, $asset, $expectedContent)
+    {
+        static::bootKernel();
+        /** @var GetNelmioAsset $getNelmioAsset */
+        $getNelmioAsset = self::getContainer()->get('nelmio_api_doc.render_docs.html.asset');
+        $twigFunction = $getNelmioAsset->toTwigFunction($mode);
+        self::assertSame($expectedContent, $twigFunction->getCallable()->__invoke($asset, $mode));
+    }
+
+    public function provideAsset()
+    {
+        $cdnDir = 'https://cdn.jsdelivr.net/gh/nelmio/NelmioApiDocBundle/Resources/public';
+        $resourceDir = __DIR__.'/../../../Resources/public';
+
+        return $this->provideCss($cdnDir, $resourceDir)
+            + $this->provideJs($cdnDir, $resourceDir)
+            + $this->provideImage($cdnDir);
+    }
+
+    private function provideCss($cdnDir, $resourceDir)
+    {
+        return [
+            'bundled css' => [
+                AssetsMode::BUNDLE,
+                'style.css',
+                '<link rel="stylesheet" href="/bundles/nelmioapidoc/style.css">',
+            ],
+            'cdn css' => [
+                AssetsMode::CDN,
+                'style.css',
+                '<link rel="stylesheet" href="'.$cdnDir.'/style.css">',
+            ],
+            'offline css' => [
+                AssetsMode::OFFLINE,
+                'style.css',
+                '<style>'.file_get_contents($resourceDir.'/style.css').'</style>',
+            ],
+            'external css' => [
+                AssetsMode::BUNDLE,
+                'https://cdn.com/my.css',
+                '<link rel="stylesheet" href="https://cdn.com/my.css">',
+            ],
+        ];
+    }
+
+    private function provideJs($cdnDir, $resourceDir)
+    {
+        return [
+            'bundled js' => [
+                AssetsMode::BUNDLE,
+                'init-swagger-ui.js',
+                '<script src="/bundles/nelmioapidoc/init-swagger-ui.js"></script>',
+            ],
+            'cdn js' => [
+                AssetsMode::CDN,
+                'init-swagger-ui.js',
+                '<script src="'.$cdnDir.'/init-swagger-ui.js"></script>',
+            ],
+            'offline js' => [
+                AssetsMode::OFFLINE,
+                'init-swagger-ui.js',
+                '<script>'.file_get_contents($resourceDir.'/init-swagger-ui.js').'</script>',
+            ],
+            'external js' => [
+                AssetsMode::BUNDLE,
+                'https://cdn.com/my.js',
+                '<script src="https://cdn.com/my.js"></script>',
+            ],
+        ];
+    }
+
+    private function provideImage($cdnDir)
+    {
+        return [
+            'bundled image' => [
+                AssetsMode::BUNDLE,
+                'logo.png',
+                '/bundles/nelmioapidoc/logo.png',
+            ],
+            'cdn image' => [
+                AssetsMode::CDN,
+                'logo.png',
+                $cdnDir.'/logo.png',
+            ],
+            'offline image fallbacks to cdn' => [
+                AssetsMode::OFFLINE,
+                'logo.png',
+                $cdnDir.'/logo.png',
+            ],
+        ];
+    }
+}