Formatting a list in SendGrid

Hi Bubblers :slight_smile:

I’m always quite amazed by what you can do with Bubble, a well-designed plugin and some luck! I’m almost there, just need some help for the last bit.

I’ve been able to send a list of things using the @copilot SendGrid plugin through to SendGrid. The Bubble Plugin details are ‘questionnumber’ and ‘questiontext’


In SendGrid, I have a Legacy template set up with the below code, which would bring in the Bubble Question Number and Question Text.


It comes through as:

Don’t worry about it saying ‘Image 1’ etc - that’s just any text. What I need it to look like is the below formatted list, (Ideally without the bulletpoints as the list has numbers already), and it must be able to handle an unlimited number of entries in the list

{questionnumber}. {questiontext}

{questionnumber}. {questiontext}

{questionnumber}. {questiontext}

Anyone got any ideas?

Thanks so much!!!


Been looking at a similar problem, I don’t think it is possible because you have an unknown length list (I guess). If you knew the list length you could use :firstitem, item2 etc to pull each question out 1 by 1 with it’s text. Even this method is very long winded but does work.

What you really want is to be able to send a repeating group output to email but other than capture it as an image I haven’t found a way.

I experimented with :joinwith and :mergewith but couldn’t get that to work either

Anyone else found a solution to this issue?


1 Like

Thanks so much, Simon!

I wrestled with it for a while, but in the end I went with your ‘long-winded’ approach: set a max list length of 35 and just went Item by Item. Slow, but it did work :slight_smile:

Not that it’s necessarily useful for your situation, but if you weren’t using the legacy template in Sendgrid then you can iterate through a list of JSON items. In my case I created the JSONest plugin to allow both lists and nested lists (things of things) to work with sendgrid specifically. In my case I t was a list of orderitems and those orderitems – each with list of customizations Works like a charm for this purpose. :slight_smile:

1 Like

Hey Jon, Don’t suppose you have an example of this working do you? I have just come across the same requirement again and still not figured it out.


Hi Simon,

In the end I went with your suggested ‘long-winded approach’. Did yoou look at @jon2’s JSON suggestion?

Thanks @mccjon

The JSON one is the one I would love details on as I think it is probably the answer just could do with an example/screen shot @jon2 to help me figure out how.


@simon there

The basic idea is:
Step 1 - Create JSON from your database using JSONator
Step 2 - Send that JSON you created in step 1 to SendGrid (using SendGrid Plugin by copilot)

For step 1:
There is a fully fleshed out example app and editor showing how JSONest works as well as a fairly detailed forum thread linked above, so I’ll assume that you’ll be all set to get started that to start.

For step 2 (sendgrid)
I used the @copilot plugin. There’s some learning needed to set this up and copilot has a series of videos that explain how this plugin works. I’d start there if you require a full tutorial.
Important note: You’ll need to setup an email template to receive your custom JSON at

A user makes payment on the site, which triggers an API workflow. That workflow sends an order confirmation email to the customer using sendgrid

Here’s the workflow


In bubble editor

Below is my configuration JSON.
Its unusually long and complex. I had to groom my JSON output quite a bit because my database name ids (these are the less pretty underscored_names_of_db_fields that JSONator and other plugins see) were all screwed up. This issue was, I had renamed several of my db fields in the bubble editor along the way while building my app and these do not change in the ‘back end’ after the first time you name a field. As a result, the field names in my bubble app no longer correspond to the ids that JSONator was getting from the bubble DB and so they needed to be remapped.
Word to the wise: DO NOT rename your database fields if it can be avoided.

   {"field_id" : "payment_amount_number",           "new_id" : "payment_amount",         "type" : "custom._orders", "format" : "USD" },
   {"field_id" : "purchase_card_custom_card1",      "new_id" : "billing",                "type" : "custom._orders"},
   {"field_id" : "Created By",                      "new_id" : null,                     "type" : "_all" },
   {"field_id" : "Created Date",                    "new_id" : null,                     "type" : "_all" },
   {"field_id" : "Modified Date",                   "new_id" : null,                     "type" : "_all" },
   {"field_id" : "_id",                             "new_id" : null,                     "type" : "_all" },
   {"field_id" : "stripe_card_id_text",             "new_id" : null,                     "type" : "custom.card1"},
   {"field_id" : "customer_id1_text",               "new_id" : null,                     "type" : "custom.card1"},
   {"field_id" : "c_id",                            "new_id" : null,                     "type" : "custom.card1"},
   {"field_id" : "ship_address_text",               "new_id" : "bill_address_text",      "type" : "custom.card1"},
   {"field_id" : "ship_first_name_text",            "new_id" : "bill_first_name_text",   "type" : "custom.card1"},
   {"field_id" : "ship_last_name_text",             "new_id" : "bill_last_name_text",    "type" : "custom.card1"},
   {"field_id" : "ship_address_2_text",             "new_id" : "bill_address_2_text",    "type" : "custom.card1"},
   {"field_id" : "card_brand_text",                 "new_id" : "brand",                  "type" : "custom.card1",   "format" : "boolean", "copy" : true },
   {"field_id" : "ship_phone_text",                 "new_id" : "customer_phone",         "type" : "custom._orders", "format" : "phone"},
   {"field_id" : "purchase_date1_date",             "new_id" : "purchase_date",          "type" : "custom._orders", "format" : "mmddyyyy"},
   {"field_id" : "purchase_amount_number",          "new_id" : "purchase_total_usd",     "type" : "custom._orders", "format" : "USD"},
   {"field_id" : "purchase_subtotal_amount_number", "new_id" : "purchase_subtotal_usd",  "type" : "custom._orders", "format" : "USD"},
   {"field_id" : "purchase_waiver_amount_number",   "new_id" : "purchase_waiver_usd",    "type" : "custom._orders", "format" : "USD"},
   {"field_id" : "purchase_shipping_amount_number", "new_id" : "purchase_shipping_usd",  "type" : "custom._orders", "format" : "USD"},
   {"field_id" : "purchase_discount_amount_number", "new_id" : "purchase_discount_usd",  "type" : "custom._orders", "format" : "USD"},
   {"field_id" : "purchase_tax_number",             "new_id" : "purchase_tax_usd",       "type" : "custom._orders", "format" : "USD"},
   {"field_id" : "list_of_order_items_list_custom_iterm", "new_id" : "orderitems",       "type" : "custom._orders"}, 
   {"field_id" : "stripe_card_id_text",             "new_id" : null,                     "type" : "custom._orders" },
   {"field_id" : "temp_password_text",              "new_id" : null,                     "type" : "custom._orders" },
   {"field_id" : "temp_creds_text",                 "new_id" : null,                     "type" : "custom._orders"  },
   {"field_id" : "charge_id_text",                  "new_id" : null,                     "type" : "custom._orders"  },
   {"field_id" : "type_text",                       "new_id" : "event_type_text",        "type" : "custom.iterm"  },
   {"field_id" : "completed_order_string_text",     "new_id" : null,                     "type" : "custom.iterm"  },
   {"field_id" : "ship_address_21_text",            "new_id" : "ship_address_2_text",    "type" : "custom.iterm"  },
   {"field_id" : "checkout_finish_date_date",       "new_id" : "event_finish_date",      "type" : "custom.iterm" , "format" : "DDmmmddyyyy"},
   {"field_id" : "checkout_start_date_date",        "new_id" : "event_start_date",       "type" : "custom.iterm", "format" : "DDmmmddyyyy"},
   {"field_id" : "purchased1_date",                 "new_id" : "purchase_date",          "type" : "custom.iterm", "format" : "mmddyyyy"},
   {"field_id" : "company_name_text",               "new_id" : "ship_company_text",      "type" : "custom.iterm"  },
   {"field_id" : "ship_address1_text",              "new_id" : "ship_address_text",      "type" : "custom.iterm"  },
   {"field_id" : "price_number",                    "new_id" : "price_usd",              "type" : "custom.iterm", "format" : "USD"},
   {"field_id" : "damage_waiver_number",            "new_id" : "damage_waiver_number",   "type" : "custom.iterm" },
   {"field_id" : "list_of_answers1_list_custom_answers", "new_id" : "answers",           "type" : "custom.iterm"  },
   {"field_id" : "key_text",                        "new_id" : "content_type",           "type" : "custom.answers" },
   {"field_id" : "displayed_text_text",             "new_id" : "display_name_text",      "type" : "custom.answers" },
   {"field_id" : "question_custom_question",        "new_id" : "associated_question",    "type" : "custom.answers" }]



Thanks a lot @jon2 for the detailed explanation from your plugin. This is very useful to convert datatypes into JSON.

  1. How do you manage to convert the JSON into an HTML list in Sendgrid? Do you have any example to show ? That would be awesome.

  2. I also need to concatenate the JSON created with other fields that are not stored in Bubble database but in user’s frontend. I would love to know how to perform this too.

Many thanks for your help