This document explains how to prepare InDesign files so the converter can turn them into
theme-export JSON for photo book products. Every rule here maps directly to how the converter
reads your file — follow these guidelines and the output will be correct.
1. File Packaging & Naming
Export your InDesign document as an IDML package (File → Export → InDesign Markup). Do not submit .indd files — only IDML is supported.
Place the resulting .idml file(s) inside a single .zip archive. The zip may contain one or more IDML files (e.g. separate cover and interior documents).
The converter identifies cover vs. interior files by looking for keywords in the filename:
File type
Recognized keywords in filename
Cover
-cov-cover-hc
Interior pages
-int-interior-bw
The product name displayed in the output is derived from the zip filename. Keep it clean and descriptive (e.g. nijntje-familie-210x210-hc.zip). Numbering, dimension strings, and common suffixes are automatically cleaned up.
Example zip contents: my-product-210x210-hc-cover.idml my-product-210x210-bw-interior.idml
2. Document Setup
Set Page Width and Page Height explicitly in Document Setup. These dimensions drive all pixel calculations at 300 DPI.
Set the bleed via Document Bleed Top Offset. The converter reads this to compute the bleed margin in pixels.
Use millimeters as the document unit for consistency.
Example: a 210×210 mm page with 3 mm bleed produces trim = 2480 px, bleed = 35 px, template = 2551 px.
3. Layers — The Core Concept
Layers are the single most important organizing principle. The converter decides what to do with every element — text frame, image frame, or rectangle — based on which layer it sits on.
Layer matching is case-insensitive and uses substring matching. A layer named "Variables photo above" matches the "variable" keyword.
Elements on layers that don't match any keyword are silently skipped — they won't appear in the output at all.
The table below is listed in priority order. When a layer name contains multiple keywords, the first match wins. For example, a layer named "fixed background design" contains both "background" and "fixed" — it is classified as Background because that keyword is checked before "fixed."
Priority
Layer name contains
Classification
What happens
1
attribute
Attribute
Text becomes a product-attribute placeholder (auto-filled from product data); images treated as variable
2
variable or variabel
Variable
Element is user-editable: text becomes a text placeholder, image becomes a photo placeholder
3
background
Background
Image becomes the page background; text becomes fixed (non-editable) text; colored rectangles contribute to page background color
4
fixed or statisch
Fixed
Element is static decoration: text becomes fixed text, image becomes a non-editable illustration
5
Anything else
Unrecognized
Element is ignored entirely — useful for annotations, guides, or production-only content
Every text frame and image frame must be on a recognized layer to appear in the output. If something is missing from the converted theme, the first thing to check is its layer assignment.
Priority matters for compound names: A layer named "fixed background design" is classified as Background (priority 3), not Fixed (priority 4), because "background" is matched first. If you want content to be treated as fixed decoration, make sure the layer name does not also contain "attribute", "variable"/"variabel", or "background".
Recommended layer setup: Create layers with clear names like "variable text", "variable photos", "fixed background design", "attribute text", and "statisch". Dutch equivalents (variabel, statisch) work identically.
4. Text Elements
Write text normally inside text frames — no special syntax is needed. The layer determines how it's treated:
Layer type
Output
What the end user sees
Variable
template_position_text
An editable text field. The text you write becomes the placeholderText (the default value shown to the user before they type).
Attribute
template_position_text + themevariant
An auto-filled field linked to product data. The text content is used to generate the attribute tag (lowercased, spaces become underscores). E.g. "Name Child" → tag name_child.
Fixed
object_text
Static text that the user cannot edit. Appears exactly as designed.
Unrecognized
Nothing
Text frame is skipped entirely.
The converter reads the font family, size, color, alignment, bold, and italic from the text frame's paragraph and character styles. Set these through styles rather than manual overrides when possible.
AllCaps capitalization from paragraph or character styles is applied automatically (the text is uppercased in the output).
Vertical alignment is supported: CenterAlign and BottomAlign from TextFramePreference adjust the text position within its frame.
Text alignment (horizontal) is read from the Justification attribute in paragraph styles. Supported: LeftAlign, CenterAlign, RightAlign, and all justified variants.
Size your text frames to comfortably fit the content. The converter computes a minimum height from font metrics and will expand frames that are too small, but it's better to get it right in the design.
5. Image Elements
Image frames (rectangles with placed/linked images) are classified by layer, just like text:
Layer type
Output
What it means
Variable
template_position_photo
A photo placeholder where the end user drops their own photo. The frame defines the position and size of the slot.
Background
Page bgimage
Becomes the page background image. See the Backgrounds section for details on tiling and cropping.
Fixed / Attribute
object_photo
A static illustration or design element that the user cannot change. The linked image is preserved in the output.
Unrecognized
Nothing
Image frame is skipped entirely.
Rectangles with a fill color but no linked image are ignored in image processing (they may contribute to background color detection instead).
All image frames are included regardless of size — even very small frames are preserved in the output.
Rotation of image frames is preserved and output as the angle or rotate property.
Make sure all design images are placed on a recognized layer. An image on an unlabeled or annotation layer will not appear in the output.
6. Backgrounds (Color & Image)
Each page can have a background color and/or a background image. These are detected automatically.
Background Color
The converter looks at all rectangles on recognized layers (variable, fixed, background, attribute) and picks the one with the largest area. Its fill color becomes the page bgcolor.
Rectangles with no fill, Color/Paper fill, or linked images are excluded.
Rectangles on unrecognized layers are ignored — so annotations or layout guides with colored fills won't accidentally become the background color.
Background Image
Image frames on layers containing background are treated as page backgrounds. The largest one becomes the page bgimage.
Tiled backgrounds: When a spread has 5 or more background-layer images, the converter composites them into a single SVG with all transforms preserved (including group transforms for nested InDesign groups).
Cover backgrounds: Full-spread background images on cover pages are automatically cropped per page (front/back) during upload — SVG viewBox is adjusted for vectors, rasters are uploaded directly.
Both vector (.ai, .pdf, .eps, .svg) and raster (.png, .jpg) formats are supported.
Background-layer images are excluded from the regular object_photo processing. They only appear as the page bgimage.
7. Fonts & Typography
Embed all fonts in the IDML package by placing font files (.otf, .ttf) in the Document fonts/ folder inside the package.
The converter extracts font files from the package and makes them available in the preview viewer.
Font properties are resolved from paragraph and character styles in this priority order:
Inline CharacterStyleRange overrides (directly on the text run)
Referenced CharacterStyle definition in Styles.xml
Set auto_leading (line height) explicitly in paragraph styles. The converter defaults to 120% when not specified, with a 1.2× floor.
Font names are cleaned up automatically: (OTF) and (TTF) suffixes are stripped from InDesign names.
Alignment: Set horizontal text alignment via Justification in paragraph styles.
Supported: LeftAlign, CenterAlign, RightAlign, LeftJustified, CenterJustified, RightJustified, FullyJustified.
8. Color Definitions
Define CMYK swatches using InDesign's standard naming format: C=X M=Y Y=Z K=W
The converter uses a lookup table that matches InDesign's ICC profile for accurate CMYK-to-hex conversion. The color is read from the swatch Name attribute (not the stored ColorValue, which may differ).
RGB colors are also supported and converted directly to hex.
Text font colors are resolved from the FillColor attribute in paragraph/character styles.
9. Cover Spreads & Variants
The cover file should contain a single spread with the full cover layout: back cover + spine + front cover.
The converter automatically detects the spine by looking for narrow center rectangles, then splits the spread into separate back and front cover pages.
Elements that cross the spine (spanning both back and front) are skipped. Elements outside the page bounds are also excluded.
Cover pages use the same trim dimensions as interior pages.
Multiple Cover Designs
To offer multiple cover options for the same product, include multiple cover IDML files in the zip.
Name them with a variant identifier: design-01, design-02, etc. (underscores also work: design_01).
Each cover design produces a separate JSON output file sharing the same interior pages but with different covers.
A single cover file produces one output without a variant suffix.
Multi-variant zip contents: my-product-hc-cover-design-01.idml my-product-hc-cover-design-02.idml my-product-hc-cover-design-03.idml my-product-bw-interior.idml
Every page gets its own unique template — templates are never shared between pages, even if pages have identical layouts.
Page names follow the format: {Product} | Page {N} | Customizable or {Product} | Page {N} | Fixed
A page is Customizable if it contains any user-editable elements (text placeholders or photo placeholders). Otherwise it is Fixed.
Template names follow the format: {Product} | Page {N}
Cover pages are named {Product} | FrontCover and {Product} | BackCover.
The Customizable/Fixed label is determined automatically after processing all elements on the page. You don't need to do anything special — just put elements on the right layers.
11. Photo Borders
To add a border around a photo placeholder, place a Paper-colored rectangle (white fill, Color/Paper) directly behind the photo frame.
The rectangle must be slightly larger than the photo frame on all four sides, creating a uniform border.
Requirements: the border must be uniform (max 5pt difference between sides) and no thicker than 30pt.
The converter detects these automatically and sets borderwidth and bordercolor on the photo placeholder.
If no border rectangle is found behind a photo placeholder, it will have no border (borderwidth = 0). Borders are entirely optional.
12. Multi-Language Themes
To create a theme in multiple languages from a single InDesign file, use language-prefixed layer names with a colon separator: {locale}:{layer type}
Layers without a locale prefix are shared — they appear in every language export. Use these for elements that are identical across languages (e.g. shared backgrounds, photo placeholders).
Layers with a locale prefix are language-specific — they only appear in the export for that locale.
Locale codes can be simple (NL, EN, DE) or regional (be-NL, en-US). The colon separator avoids ambiguity with dashes in locale codes.
The layer type after the colon follows the same rules as regular layers (attribute, variable, background, fixed).
If no language-prefixed layers are found, the converter produces a single output as usual (fully backward compatible).
Example layer setup for NL + EN:
background — shared background (appears in both NL and EN) variable — shared photo placeholders NL:fixed — Dutch-only decorative text EN:fixed — English-only decorative text NL:variable — Dutch text placeholders EN:variable — English text placeholders
Each language produces a separate JSON output file, similar to cover variants: my-product-NL.json, my-product-EN.json
When combined with multiple cover designs, the full cross-product is generated: my-product-design-01-NL.json, my-product-design-01-EN.json, etc.
Language-specific layers can include design changes — not just different text, but also different images, backgrounds, and layout adjustments per language.
Recommended approach: Put all language-independent elements (backgrounds, shared photos) on regular layers without a prefix. Only add locale prefixes to layers that contain language-specific content. This keeps your InDesign file clean and avoids duplicating shared elements.
The locale prefix must come before the colon and must not contain any layer classification keywords (attribute, variable, background, fixed, etc.). For example, NL:fixed is correct, but fixed:NL would not work as a locale prefix.
13. Automatically Filtered Content
Certain production-only text is automatically removed from the output, regardless of layer. You can include these freely in your InDesign file:
This filtering happens after layer classification. A text frame on an unrecognized layer is skipped before these filters even apply. These filters only affect text that would otherwise appear in the output.
14. Stacking Order & Z-Axis
The z_axis value on every element reflects its stacking order in the InDesign document (the order elements appear in the spread XML).
Elements inside groups are flattened with consecutive indices, preserving the internal order of the group.
Make sure your element stacking order is correct in InDesign — it will be reproduced exactly in the output.