Have your say in Community Polls: What was/is your greatest motivation to start your own business?
Our Partner & Developer boards on the community are moving to a brand new home: the .dev community forums! While you can still access past discussions here, for all your future app and storefront building questions, head over to the new forums.

Is there a recommended way to pass liquid templates back in an app proxy response?

Is there a recommended way to pass liquid templates back in an app proxy response?

Danh11
Shopify Partner
87 2 40

I have an app built upon the Shopify remix app template. I am passing a product card (at the moment it's Dawn's product card) back in response to a request via the shopify app proxy. Although I'm running into issues to do with escaping characters.

 

As it's my first time, I'm wondering if I am doing it correctly as it seems a little fickle and I don't think I'd be comfortable releasing it into production. The template is fine if I don't touch it, but I'd like merchants to be able to use their own template if they wanted to.

The ways I've got it working is to only use single line liquid tags (not blocks of liquid), and no double quotes inside the template as it gets messy when it comes out the other side of the json() function that I need to return a response. I might be doing this wrong?

Would be great to hear or see how others are doing this.

The remix app:

export async function action({ request }) {
  if (request.method === 'OPTIONS') return await cors(request, json({}));

  // rest of code

  const response = json( productTemplate(data) );
  response.headers.set("Content-Type", "application/liquid");
  return await cors(request, response);
}

Client/theme

  async storeHtml(response) {
    const responseText = await response.text();
    const rawHtml = responseText;
    const htmlCleaned = rawHtml.replace(/\\n/g, '');
    const parser = new DOMParser();
    const doc = parser.parseFromString(htmlCleaned, 'text/html');
    const card = doc.querySelector('.product-card');

    if (card !== null) {
      const cardHtmlString = card.outerHTML;
      this.data.html = cardHtmlString;
    }
  }

 

Replies 5 (5)

Liam
Community Manager
3108 344 892

Hi Danh11,

 

Your approach seems to be right. However, the escaping issue commonly occurs when you are sending a response from the server to the client.

 

The problem you are facing is related to the characters in your JSON string that needs to be escaped. You are replacing the newline characters with an empty string using replace(/\\n/g, ''). It's a good approach but you need to consider other characters as which needs to be escaped such as backspace, form feed, carriage return, horizontal tab, double quote, and backslash.

 

Here's how you can escape these characters:

const htmlCleaned = rawHtml.replace(/[\n\r\t\\'"]/g, function(char) {
  switch (char) {
    case '\n': return '\\n';
    case '\r': return '\\r';
    case '\t': return '\\';
    case '\\': return '\\\\';
    case "'": return "\\'";
    case '"': return '\\"';
    default: return char;
  }
});

This code will replace all the special characters with their escaped versions. This way, your JSON string will be correctly formatted and won't face any issues related to escaping characters.

 

Hope this helps!

Liam | Developer Advocate @ Shopify 
 - Was my reply helpful? Click Like to let me know! 
 - Was your question answered? Mark it as an Accepted Solution
 - To learn more visit Shopify.dev or the Shopify Web Design and Development Blog

Danh11
Shopify Partner
87 2 40

Unfortunately I couldn't get this one working. I spent some time on it and wasn't able to get anywhere. In the end I've changed how I'm going about this. May come back to it sometime later 🙂

NickShi
Shopify Partner
26 3 4

Hi @Danh11 , I have same problem as you, did you get a better solution now ? many thanks.

- If helpful then please Likes and make it as a Solution.
- If you want to develop a store/app, or need custom software development services Email Me
Danh11
Shopify Partner
87 2 40

No I haven't attempted it since, sorry!

DodoDev
Shopify Partner
4 0 0

Hi,
Maybe you are looking for: `liquid()` ? You can use it inside your action handling the proxy logic.

const { session, liquid } = await authenticate.public.appProxy(request)

See https://github.com/Shopify/shopify-app-template-remix/issues/295#issuecomment-1710586193 .

Not sure it works, I am stuck at trying to display the result!