Icons not loading when Drupal installed in a sub-directory

Created on 18 August 2022, about 2 years ago
Updated 7 July 2023, over 1 year ago

Problem/Motivation

The link in the module code to the svg files is hard coded to point to the domain root of the site, not the base path, resulting in a 404 error for the SVG file if the module is installed in a site with a sub-directory.
i.e. this link:
/modules/contrib/better_social_sharing_buttons/assets/dist/sprites/social-icons--no-color.svg
It should point to:
/subdirectory/modules/contrib/better_social_sharing_buttons/assets/dist/sprites/social-icons--no-color.svg

Steps to reproduce

Install Drupal 9 in a sub-directory - e.g. http://localhost/subdirectory/ and then install the module. The output of the SVG icons appears blank. View the browser console and you can see the 404 error being reported for the missing SVG file.

Proposed resolution

Two solutions (#1 is messy, so #2 would be a better solution):
1) Edit the twig template to include {{base_path}} - for example:

2) Edit better_social_sharing_buttons.module and include the base_path in:
function better_social_sharing_buttons_preprocess_better_social_sharing_buttons

Remaining tasks

User interface changes

API changes

Data model changes

🐛 Bug report
Status

Fixed

Version

4.0

Component

Code

Created by

🇬🇧United Kingdom richardprice UK, Spain, Worldwide

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • First commit to issue fork.
  • Open on Drupal.org →
    Core: 10.1.x + Environment: PHP 8.1 & MySQL 5.7
    last update over 1 year ago
    Waiting for branch to pass
  • @codebymikey opened merge request.
  • Status changed to Needs review over 1 year ago
  • Open on Drupal.org →
    Core: 10.1.x + Environment: PHP 8.1 & MySQL 5.7
    last update over 1 year ago
    Waiting for branch to pass
  • Provided a patch which resolves the relevant URL using Drupal's Uri resolver rather than accessing the global $base_url variable.

  • Open on Drupal.org →
    Core: 10.1.x + Environment: PHP 8.1 & MySQL 5.7
    last update over 1 year ago
    Waiting for branch to pass
  • Status changed to Fixed over 1 year ago
  • 🇫🇮Finland phonkala

    With the #9 patch and after installing 4.x-dev, I've been getting this error:

    The website encountered an unexpected error. Please try again later.
    
    Twig\Error\LoaderError: Template "/a/b/c/modules/contrib/better_social_sharing_buttons/assets/dist/sprites/social-icons--square.svg" is not defined in "modules/contrib/better_social_sharing_buttons/templates/better-social-sharing-buttons.html.twig" at line 4. in Twig\Loader\ChainLoader->getCacheKey() (line 99 of /home/myhome/domains/mydomain.com/public_html/a/b/c/vendor/twig/twig/src/Loader/ChainLoader.php).

    After some testing, the issue I am having is that whenever I have actual whole URL with domain and/or protocol (or the one that is written in the module) in the module file function better_social_sharing_buttons_preprocess_better_social_sharing_buttons(), line where you set the $variables['social_buttons_sprite'], I keep getting this error. Well, even if I remove the function Url::fromUri() completely from that line and just use a static string with correct subfolder path like "/a/b/c/path-here", I get same error. If I use just "/path-here", no error but the icons also won't load as the path is missing the subfolders. Manually adding protocol/domain to the url string also generates the error. If I set the actual subfolder path inside Twig template instead of the variable in module file, everything works fine.

    Based on this fix from related issue from another module ( https://www.drupal.org/files/issues/2022-09-28/3312270-claro-menu-twig-f... ), I added ignore missing at the end of the include in Twig file, and everything works again, icons do load nicely and no errors. Feels a bit weird to me, as the svg file does exist, can be opened in browser, Chrome devel console shows the correct path etc. But I just wanted to add this here, maybe there is still some part in the code that doesn't take every case into consideration.

  • Status changed to Needs work over 1 year ago
  • 🇺🇸United States shelane

    phonkala, what method are you using to add the sharing to your page? Through block place, through a field, or through a twig file call? How is your site run? Is it at the root of the domain or a subdirectory?

  • 🇫🇮Finland phonkala

    Hey @shelane!

    My site is running in subdir in my dev environment, that is what I was trying indicate with the "/a/b/c" folder/url structure. The share buttons are in a block, in the Social Bar region of Olivero. Running Drupal 10.1.1.

    I just did a fresh install of Drupal to subfolder "mydomain.dev/a/b/c/web/" to test this, with just Better Social Sharing Buttons installed. If I install the stable version of this module and place the share buttons into a block, the url path of the svg file points to "mydomain.dev/modules/contrib/better_social_sharing_buttons/assets/dist/sprites/social-icons--square.svg" so it is missing the subfolders and the icons won't show up. When I install the dev version, I once again get the same error I mentioned before. Here is the stack trace of it:

    Twig\Environment->getTemplateClass() (Line: 204)
    Drupal\Core\Template\TwigEnvironment->getTemplateClass() (Line: 319)
    Twig\Template->loadTemplate() (Line: 45)
    __TwigTemplate_95a24dd74af07297fa12b28b9477ba05->doDisplay() (Line: 394)
    Twig\Template->displayWithErrorHandling() (Line: 367)
    Twig\Template->display() (Line: 379)
    Twig\Template->render() (Line: 40)
    Twig\TemplateWrapper->render() (Line: 53)
    twig_render_template() (Line: 372)
    Drupal\Core\Theme\ThemeManager->render() (Line: 436)
    Drupal\Core\Render\Renderer->doRender() (Line: 204)
    Drupal\Core\Render\Renderer->render() (Line: 474)
    Drupal\Core\Template\TwigExtension->escapeFilter() (Line: 90)
    __TwigTemplate_d1731b982d08fea58c1650bd7940916b->block_content() (Line: 171)
    Twig\Template->displayBlock() (Line: 74)
    __TwigTemplate_d1731b982d08fea58c1650bd7940916b->doDisplay() (Line: 394)
    Twig\Template->displayWithErrorHandling() (Line: 367)
    Twig\Template->display() (Line: 379)
    Twig\Template->render() (Line: 40)
    Twig\TemplateWrapper->render() (Line: 53)
    twig_render_template() (Line: 372)
    Drupal\Core\Theme\ThemeManager->render() (Line: 436)
    Drupal\Core\Render\Renderer->doRender() (Line: 449)
    Drupal\Core\Render\Renderer->doRender() (Line: 204)
    Drupal\Core\Render\Renderer->render() (Line: 474)
    Drupal\Core\Template\TwigExtension->escapeFilter() (Line: 176)
    __TwigTemplate_421e2c49b82c005693398eac1d302f3e->doDisplay() (Line: 394)
    Twig\Template->displayWithErrorHandling() (Line: 367)
    Twig\Template->display() (Line: 379)
    Twig\Template->render() (Line: 40)
    Twig\TemplateWrapper->render() (Line: 53)
    twig_render_template() (Line: 372)
    Drupal\Core\Theme\ThemeManager->render() (Line: 436)
    Drupal\Core\Render\Renderer->doRender() (Line: 204)
    Drupal\Core\Render\Renderer->render() (Line: 474)
    Drupal\Core\Template\TwigExtension->escapeFilter() (Line: 93)
    __TwigTemplate_70a02092721b37e59a3f82beed4828fe->doDisplay() (Line: 394)
    Twig\Template->displayWithErrorHandling() (Line: 367)
    Twig\Template->display() (Line: 379)
    Twig\Template->render() (Line: 40)
    Twig\TemplateWrapper->render() (Line: 53)
    twig_render_template() (Line: 372)
    Drupal\Core\Theme\ThemeManager->render() (Line: 436)
    Drupal\Core\Render\Renderer->doRender() (Line: 204)
    Drupal\Core\Render\Renderer->render() (Line: 158)
    Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 583)
    Drupal\Core\Render\Renderer->executeInRenderContext() (Line: 159)
    Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse() (Line: 90)
    Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray()
    call_user_func() (Line: 111)
    Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch() (Line: 171)
    Symfony\Component\HttpKernel\HttpKernel->handleRaw() (Line: 74)
    Symfony\Component\HttpKernel\HttpKernel->handle() (Line: 58)
    Drupal\Core\StackMiddleware\Session->handle() (Line: 48)
    Drupal\Core\StackMiddleware\KernelPreHandle->handle() (Line: 106)
    Drupal\page_cache\StackMiddleware\PageCache->pass() (Line: 85)
    Drupal\page_cache\StackMiddleware\PageCache->handle() (Line: 48)
    Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle() (Line: 51)
    Drupal\Core\StackMiddleware\NegotiationMiddleware->handle() (Line: 51)
    Drupal\Core\StackMiddleware\StackedHttpKernel->handle() (Line: 704)
    Drupal\Core\DrupalKernel->handle() (Line: 19)

    And if I then just add the "ignore missing" to the include in the module twig template file:

    {# --- Include svg sprite --- #}
    <div style="display: none">{% include social_buttons_sprite ignore missing %}</div>

    everything starts to work correctly, svg url has the correct subfolder structure.

    Also tested with Claro theme in Drupal 10, same issue.

  • 🇫🇮Finland phonkala

    I just realized, using the stable version of the module, there is actual content in the first div of the twig file:

    {# --- Include svg sprite --- #}
    <div style="display: none">{% include social_buttons_sprite %}</div>

    When I'm checking it via Chrome dev console or just source code, inside the div, with stable version, there is the svg html tag and all it's inner content (defs, symbols, paths etc.).

    When using the dev version with the "ignore missing" added to twig file include (to bypass the error I keep getting), that div is completely empty for me (<div style="display: none"></div>). So the "ignore missing" is clearly filling it's purpose, I guess the svg file just is not found for whatever reason in twig template and twig is ignoring it. However, the icons do work perfectly, even after clearing Drupal/browser cache.

  • 🇫🇮Finland phonkala

    Ahh I think I figured it out. I was thinking the

    {# --- Include svg sprite --- #}
    <div style="display: none">{% include social_buttons_sprite %}</div>

    is required in Twig to even use the icons, but I guess it's there just for preloading purposes?

    I believe using include for that actually includes the contents of the file into the code and doesn't actually even preload the image file. Also, based on the link I added at the end of my last comment (#15), there might be permission issues using include to load svg files inside Twig.

    I googled how svg files should be preloaded in html and found this: https://stackoverflow.com/questions/62377727/how-to-preload-an-svg-image...

    So based on that, I chanced the

    {# --- Include svg sprite --- #}
    <div style="display: none">{% include social_buttons_sprite %}</div>

    into

    {# --- Include svg sprite --- #}
    <div style="display: none"><link rel="preload" href="{{ social_buttons_sprite }}" as="image" type="image/svg+xml" crossorigin="anonymous" /></div>

    Now everything seems to work fine, no errors and icons do show up.

    • shelane committed 9ad474d8 on 4.x
      Issue #3304574 by codebymikey, shelane, MaxMendez, phonkala,...
  • Status changed to Fixed over 1 year ago
  • Automatically closed - issue fixed for 2 weeks with no activity.

Production build 0.71.5 2024