[{"data":1,"prerenderedAt":322},["ShallowReactive",2],{"\u002Fdocs\u002Fbuilding-templates-in-bluepic-studio":3},{"id":4,"title":5,"body":6,"category":311,"date":312,"description":313,"extension":314,"heroImage":315,"meta":316,"navigation":317,"path":318,"readingMinutes":206,"seo":319,"stem":320,"tool":311,"__hash__":321},"docs\u002Fdocs\u002Fbuilding-templates-in-bluepic-studio.md","Building templates in Bluepic Studio",{"type":7,"value":8,"toc":302},"minimark",[9,14,30,38,42,50,72,83,87,90,109,113,127,216,222,226,232,240,254,258,269,273,298],[10,11,13],"h2",{"id":12},"design-once-render-forever","Design once, render forever",[15,16,17,24,25,29],"p",{},[18,19,23],"a",{"href":20,"rel":21},"https:\u002F\u002Fbx-studio.bluepic.io",[22],"nofollow","Bluepic Studio"," is where the actual design work happens — the layout, the fonts, the exact pixel a logo sits at. Everything downstream (the ",[18,26,28],{"href":27},"\u002Fdocs\u002Fapi-reference","render API",", batch jobs, personalization) just fills in values on a template you already built visually. You never hand-write the JSON a template is made of; Studio is the editor for it.",[15,31,32,33,37],{},"This guide covers the Studio side specifically: creating a template, wiring up the parts that should change per-render, and finding the ID your code needs. If you're looking for the raw-IDML path instead — importing an existing InDesign file without touching Studio's canvas — see ",[18,34,36],{"href":35},"\u002Fdocs\u002Fautomate-indesign-projects","Automate InDesign projects",".",[10,39,41],{"id":40},"create-a-template","Create a template",[15,43,44,45,49],{},"From the templates view, ",[46,47,48],"strong",{},"Create Template"," opens three starting points:",[51,52,53,60,66],"ul",{},[54,55,56,59],"li",{},[46,57,58],{},"Empty Template"," — a blank canvas at a size you pick.",[54,61,62,65],{},[46,63,64],{},"Presets"," — common starting layouts.",[54,67,68,71],{},[46,69,70],{},"Import from IDML"," — bring in an existing InDesign export as an editable Studio template, rather than rendering it raw.",[15,73,74,75,79,80,37],{},"Pick a size from the aspect-ratio grid (square, portrait 4:5, story 9:16, and a handful of others), or set exact dimensions — this is the pixel size every render comes back at unless a request overrides ",[76,77,78],"code",{},"width","\u002F",[76,81,82],{},"height",[10,84,86],{"id":85},"the-editor","The editor",[15,88,89],{},"The canvas works like any layered design tool — text, image, shape, and pen tools on the toolbar, a layers panel on the right, and a property panel on the left for whatever's selected: position and size, fill and stroke, opacity, and (for text) content, font, size and alignment.",[15,91,92,93,99,100,103,104,108],{},"The part that matters for automation is the ",[46,94,95,98],{},[76,96,97],{},"fx"," expression icon"," in the toolbar. Any numeric property — position, size, rotation, opacity — can be bound to an expression instead of a fixed number, and an expression can repeat one element a computed number of times: a rectangle whose count is ",[76,101,102],{},"body.lines.length",", say, drawn once and multiplied automatically at render time. Design the element once; let the expression handle \"one per line,\" \"one per row,\" or \"one per item in the data\" — see the ",[18,105,107],{"href":106},"\u002F#how-it-works","live example on the homepage"," for exactly this pattern.",[10,110,112],{"id":111},"connect-input-fields","Connect input fields",[15,114,115,118,119,122,123,126],{},[46,116,117],{},"Add Input Field",", then click the element you want to expose. That element's editable property (its text content, its image source, sometimes its fill color) becomes a ",[46,120,121],{},"named field"," — the name you give it here is the exact key your API request's ",[76,124,125],{},"data"," object uses later:",[128,129,134],"pre",{"className":130,"code":131,"language":132,"meta":133,"style":133},"language-json shiki shiki-themes github-dark","{\n  \"templateId\": \"efa8ff2c-262b-4488-b8cf-e01521c6fbb5\",\n  \"data\": {\n    \"headline_text_content\": \"Ship it Friday\",\n    \"avatar_image\": { \"src\": \"https:\u002F\u002Fcdn.example.com\u002Favatar.jpg\" }\n  }\n}\n","json","",[76,135,136,145,162,171,184,204,210],{"__ignoreMap":133},[137,138,141],"span",{"class":139,"line":140},"line",1,[137,142,144],{"class":143},"s95oV","{\n",[137,146,148,152,155,159],{"class":139,"line":147},2,[137,149,151],{"class":150},"sDLfK","  \"templateId\"",[137,153,154],{"class":143},": ",[137,156,158],{"class":157},"sU2Wk","\"efa8ff2c-262b-4488-b8cf-e01521c6fbb5\"",[137,160,161],{"class":143},",\n",[137,163,165,168],{"class":139,"line":164},3,[137,166,167],{"class":150},"  \"data\"",[137,169,170],{"class":143},": {\n",[137,172,174,177,179,182],{"class":139,"line":173},4,[137,175,176],{"class":150},"    \"headline_text_content\"",[137,178,154],{"class":143},[137,180,181],{"class":157},"\"Ship it Friday\"",[137,183,161],{"class":143},[137,185,187,190,193,196,198,201],{"class":139,"line":186},5,[137,188,189],{"class":150},"    \"avatar_image\"",[137,191,192],{"class":143},": { ",[137,194,195],{"class":150},"\"src\"",[137,197,154],{"class":143},[137,199,200],{"class":157},"\"https:\u002F\u002Fcdn.example.com\u002Favatar.jpg\"",[137,202,203],{"class":143}," }\n",[137,205,207],{"class":139,"line":206},6,[137,208,209],{"class":143},"  }\n",[137,211,213],{"class":139,"line":212},7,[137,214,215],{"class":143},"}\n",[15,217,218,221],{},[46,219,220],{},"Show Input Fields"," toggles a preview of every field you've wired up so far, letting you check names and defaults before you publish. Anything you don't expose as a field stays fixed — logos, backgrounds, decorative shapes never need a field at all.",[10,223,225],{"id":224},"publish-and-find-your-template-id","Publish, and find your template ID",[15,227,228,231],{},[46,229,230],{},"Publish"," makes the template renderable via the API. The ID itself is simpler than a separate \"copy ID\" step: it's the UUID already sitting in your browser's address bar while you're editing —",[128,233,238],{"className":234,"code":236,"language":237},[235],"language-text","https:\u002F\u002Fbx-studio.bluepic.io\u002Feditor\u002Fefa8ff2c-262b-4488-b8cf-e01521c6fbb5\n                                       └──────────────── templateId ────────────────┘\n","text",[76,239,236],{"__ignoreMap":133},[15,241,242,243,246,247,253],{},"— the same string goes straight into ",[76,244,245],{},"templateId"," on a ",[18,248,250],{"href":249},"\u002Fdocs\u002Fapi-reference#render-a-studio-template",[76,251,252],{},"POST \u002Fapi\u002Frender"," call.",[10,255,257],{"id":256},"sharing-url-vs-the-api","Sharing URL vs. the API",[15,259,260,261,264,265,268],{},"Studio's settings panel (the gear icon next to Publish) also offers a ",[46,262,263],{},"Sharing URL"," — a public, no-code page where anyone can fill in the fields and export an image by hand, useful for handing a template to someone who isn't writing code at all. That's a different mechanism from calling ",[76,266,267],{},"\u002Fapi\u002Frender"," directly: the sharing URL is for a human filling in a form once; the API is for your own backend rendering the same template hundreds of times from data it already has. Both read the same published template and the same input fields — pick whichever matches who's actually triggering the render.",[10,270,272],{"id":271},"next-steps","Next steps",[51,274,275,286,293],{},[54,276,277,280,281,283,284,37],{},[18,278,279],{"href":27},"API reference"," — the exact request shape for ",[76,282,267],{},", once you have a ",[76,285,245],{},[54,287,288,289,37],{},"Try it immediately with the demo template in the ",[18,290,292],{"href":291},"\u002Fidml\u002Fapi","interactive playground",[54,294,295,296,37],{},"Need the raw-IDML path instead of designing in Studio? See ",[18,297,36],{"href":35},[299,300,301],"style",{},"html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":133,"searchDepth":147,"depth":147,"links":303},[304,305,306,307,308,309,310],{"id":12,"depth":147,"text":13},{"id":40,"depth":147,"text":41},{"id":85,"depth":147,"text":86},{"id":111,"depth":147,"text":112},{"id":224,"depth":147,"text":225},{"id":256,"depth":147,"text":257},{"id":271,"depth":147,"text":272},"platform","2026-07-16","Design a template visually in Bluepic Studio — elements, expressions and input fields — then find its ID and drive it from your own code with a single POST \u002Fapi\u002Frender call.","md","\u002Fdocs-images\u002Fbuilding-templates-in-bluepic-studio.svg",{},true,"\u002Fdocs\u002Fbuilding-templates-in-bluepic-studio",{"title":5,"description":313},"docs\u002Fbuilding-templates-in-bluepic-studio","qwUwqy4K1AWxbV7nan0lGn4GGl8KEoKHrHRDAOBYQqM",1784233655648]