Shopify themes, liquid, logos, and UX
I want to render a snippet this name is defined by a variable.
{% assign template_name = 'page-' | append: page.template_suffix %} {% render template_name %}
But it occurs error that show "Syntax error in tag 'render' - Template name must be a quoted string".
"include" tag can render a snippet this name is defined by a variable.
Why "render" tag can't do it?
Unfortunately, render doesn't accept dynamic names, most probably by design and taking into consideration the performance impact.
Well, that's a bummer! This would have saved me from having to create a bunch of individual templates. 😫
@Visely-Team @masahiro @jacobgraf
Would you happen to know any alternatives for this?
Thank you!
I ended up double-checking with Shopify to make sure "include" wouldn't be deprecated. They confirmed they have no plans to deprecate it, so, for now, this is the solution I came up with and it works great! This approach will not work with "render".
<!-- Product-Specific Content -->
{% assign snippet = 'product-content-' | append: product.handle %}
{% capture snippet_content %}{% include snippet %}{% endcapture %}
{% unless snippet_content contains "Liquid error" %}
{{ snippet_content }}
{% endunless %}
I used this workaround, by appending an empty string the variable name is transformed into a string.
{%- render variable_name | append: "" -%}
Perfect. That worked for me. Thank you.
That workaround is clearly relying on a bug. Intentionally relying on a bug is fragile to changes we make to liquid or Shopify's extensions to liquid, since it puts you code at risk from breaking from a bug fix.
To learn more visit the Shopify Help Center or the Community Blog.
Thanks, Dylan, it was NOT clearly intentional. Since `render` only allows strings I was simply transforming the variable into a string (because the variable is a string already) . I also saw that you were very quick to fix the bug on Github.
My use case was simple, I had a list of icon snippets that could be selected in a section.
{% assign snippet_name = section.settings.snippet_name %}
{% include snippet_name %}
In order to achieve the same result with `render` I will have to use a switch case or something similar that will make the code way more verbose.
{% assign snippet_name = section.settings.snippet_name %}
{% case snippet_name %}
{% when "snippet_1" %}
{% render "snippet_1" %}
{% when "snippet_2" %}
{% render "snippet_2" %}
{% when "snippet_3" %}
{% render "snippet_3" %}
...
...
...
...
{% endcase %}
But thank you again for the clarification and for fixing the bug so fast.
I'm sorry that I jumped to conclusions about your intentions with the workaround. I suppose you are not aware that the render tag doesn't have a filter. Liquid is still not strict enough to make this clear to the author, since although sections are parsed in a stricter mode, this now means we need multiple levels of strictness to warn about these problems in a backwards compatible way. Specifically, the lack of strictness comes from unanchored regex matching for the tag syntax.
> Why "render" tag can't do it?
The primary reason for the restriction is to enable better performance optimizations by being able to statically determine the dependencies for the liquid template, to better allow the code and data needed to render the template to be batch loaded upfront. Dynamic template loading could potentially also be a concern for readability of the liquid code, where it makes it less clear what snippet it could/should depend on.
> In order to achieve the same result with `render` I will have to use a switch case or something similar that will make the code way more verbose.
Where possibly, consider whether this can be made less dynamic. For instance, passing variables to a snippet is one possible way of passing something dynamic into a snippet.
If a truly dynamic render is needed, then a case tag is definitely an alternative. I wouldn't expect this would need to support all the snippets as possible targets for an include, which could reduce the verbosity and make it clearer which snippets are actually intended to possibly be rendered from that tag (e.g. your icon snippets). If this dynamic render is actually needed in multiple places, then it would also be possible to avoid this duplication by moving this case tag to a generic snippet for that use case (e.g. generic icon snippet), where it can be passed a variable to to indicate which snippet to render (e.g. icon name).
To learn more visit the Shopify Help Center or the Community Blog.
How about this use case?
{%- assign icons = 'handmade,handraised,fluted,made-shoppe,made-borough,made-charnwood' | split: ',' -%}
{%- for icon in icons -%}
<li>
{%- render 'icon-' | append: icon -%}
</li>
{%- endfor -%}
You can statically define which files are being imported, I can do the below in Twig but not in Liquid
{% var icons = ['handmade', 'handraised', 'fluted', 'made-shoppe', 'made-borough', 'made-charnwood'] %}
{% for icon in icons %}
<li>
{% include 'icon-' ~ icon %}
</li>
{% endfor %}
There are so many places (even including the Dawn theme codebase as well!) this could be useful to reduce drastically code complexity. In fact this is more readable than having a page long of cases.
Hi @Dylan_Thacker-S,
Can you maybe explain why it is not possible to render snippets based on a variable name? The use case @flavioccf described earlier is exact the same as mine and in my opinion the workaround, which apparently relies on a bug, is a pretty clean way to render variabel snippets such as icons.
Any thoughts on a good way to render a snippet by a variable name, without having to write a case with all possible snippet names? (Like @flavioccf described)
That why Shopify is a bad platform for developers.
June brought summer energy to our community. Members jumped in with solutions, clicked ...
By JasonH Jun 5, 2025Learn how to build powerful custom workflows in Shopify Flow with expert guidance from ...
By Jacqui May 7, 2025Did You Know? May is named after Maia, the Roman goddess of growth and flourishing! ...
By JasonH May 2, 2025