A space to discuss online store customization, theme development, and Liquid templating.
Is it possible to set the page title and meta description through an app using the frontend app proxy?
This is for SEO purposes so I can't just do it with JS after the page has loaded.
I found some threads saying it wasn't possible but they were 3+ years old. I'm just wondering if anything has changed?
Thanks!
Solved! Go to the solution
This is an accepted solution.
You're absolutely right, it's not ideal.
Here is a better way.
In your app_proxy layout template:
<!-- assign content --> <%- if @page_title -%> {% capture page_title %} <%= @page_title %> {% endcapture %} <%- end -%> <%- if @meta_desc -%> {% capture page_description %} <%= @meta_desc %> {% endcapture %} <%- end -%> {% capture content_for_layout %} <%= yield %> {% endcapture %}
Then in your app_proxy controller:
@page_title = "Some Page Title" @meta_desc = "Some meta description" render layout: "app_proxy", content_type: 'application/liquid'
Much cleaner and no API hits!
Hi @Andrew-W,
A framed page cannot affect the parent page, so this isn't possible still. You would need to use the page API (product API if it's products, collection API if it's a collection page, etc.) to change the SEO details.
To learn more visit the Shopify Help Center or the Community Blog.
I just realized how incorrect my response was. Whoops! Of course the APIs I mentioned won't be helpful for you to set the SEO details, as it's an app proxy page (/a/something, for example) rather than a Shopify object page. I believe you could do this through editing the theme using liquid. Let me look into it a bit and get back to you.
Cheers,
To learn more visit the Shopify Help Center or the Community Blog.
So just in case anyone finds this through searching.
So in rails I created a layout template with this content:
app_proxy.html.erb
{%- layout none -%} <%= @theme.value.html_safe %>
The first line is important because that tells Shopify to render the page without any of the normal layout.
Then in controller I load the layout/theme.liquid from the theme through the API so I can change the content of it. I do a simple find and replace on the title tag and something similar (but unfortunately not very "nice" because of the way it is in the template) with the meta description. Then I put my content in with the doing a simple find an replace on the main content liquid tag. I then make sure to send this all back to Shopify with the application/liquid header so that Shopify then renders the full page as normal. Something like this:
ShopifyAPI::Base.activate_session(ShopifyAPI::Session.new(domain: @shop.shopify_domain, token: @shop.shopify_token, api_version: '2019-04')) shop_name = ShopifyAPI::Shop.current.name site_name = " - #{shop_name}" page_title.concat(site_name) meta_desc = "</title><meta name='description' content='#{meta_desc}'>" @theme = ShopifyAPI::Asset.find('layout/theme.liquid') content = render_to_string "index", format: :html, layout: false @theme.value.sub!('{{ content_for_layout }}', content) @theme.value.sub!('{{ page_title }}', page_title) @theme.value.sub!('</title>', meta_desc) render layout: "app_proxy", content_type: 'application/liquid'
It's not a perfect solution, but it does the job!
Thanks to Ole Thorup for his input on the Shopify Slack Partners Slack workspace.
But won't this cause issue? As
@theme = ShopifyAPI::Asset.find('layout/theme.liquid')
is an API call and will slow things down and not to mention API limits (2/s and 40 leaky bucket max) and can not be scaled.
This is an accepted solution.
You're absolutely right, it's not ideal.
Here is a better way.
In your app_proxy layout template:
<!-- assign content --> <%- if @page_title -%> {% capture page_title %} <%= @page_title %> {% endcapture %} <%- end -%> <%- if @meta_desc -%> {% capture page_description %} <%= @meta_desc %> {% endcapture %} <%- end -%> {% capture content_for_layout %} <%= yield %> {% endcapture %}
Then in your app_proxy controller:
@page_title = "Some Page Title" @meta_desc = "Some meta description" render layout: "app_proxy", content_type: 'application/liquid'
Much cleaner and no API hits!
Is there anyway to do the same thing for facebook (ex: og:image) and twitter (ex:twitter:image) metatags?