store-shots

Files

Every key of the files the tool keeps in your app, with what it does, from the schema itself.

The tool keeps an app's setup in three kinds of file. Each has a JSON Schema in schema/, so an editor checks and completes it as you type.

store-shots.config.json

KeyTypeWhat it is
projectNametextThe app's name in the editors and in contact sheets.
bundleIdtext, optionalThe iOS bundle id, for App Store Connect.
defaultLocaletextThe language other languages start from, and whose copy and captures fill gaps.
localeslist of textEvery App Store language the app's screenshots and listing are made in (e.g. en-US, de-DE).
pathsobjectWhere the tool reads and writes, relative to the app; the defaults suit nearly every app.
paths.manifesttextThe screens and pages. Default: "store/manifest.json".
paths.contenttextThe copy, one file per language. Default: "store/content".
paths.rawtextThe captures, by device family and language. Default: "store/raw".
paths.assetstextFonts, logos, backgrounds and layer art. Default: "store/assets".
paths.outputScreenshotstextWhere the App Store screenshots go, for fastlane deliver. Default: "fastlane/screenshots".
paths.outputPlaytextGoogle Play (supply) metadata root; screenshots go under <locale>/images/phoneScreenshots/. Default: "fastlane/metadata/android".
paths.metadatatextThe store text, one folder per language, for fastlane deliver. Default: "fastlane/metadata".
paths.generatedtextPages, iPhone Duo, header and search images, events, contact sheets; not committed. Default: "store/generated".
paths.previewstextApp Preview videos, <previews>/<locale>/*.mp4|m4v|mov; readiness checks them and asc push default uploads them. Default: "store/previews".
targetslist of enumThe devices to render for, by id (iphone-6.9-1320x2868, header-3840x1646, ...).
sourceDevicesmap of texttarget id -> raw capture device folder name under paths.raw
brandobjectThe app's look: fonts, colours and the default background. A theme sets these.
brand.fontobjectThe body font.
brand.font.familytextThe font family, as Google Fonts names it, or a family added locally. Default: "Inter".
brand.font.source"google" or "local"Where store-shots fonts add gets it from. Default: "google".
brand.font.weightslist of whole numberThe weights downloaded; headlines use the heaviest a headline font lists. Default: [400, 600, 700].
brand.font.fallbackslist of textExtra families tried after family, in order (must be local: fonts add). Bundled fallbacks are appended automatically. Default: [].
brand.headlineFontobject, optionalOptional display face for headlines (e.g. a serif); body copy keeps font.
brand.headlineFont.familytextThe font family, as Google Fonts names it, or a family added locally. Default: "Inter".
brand.headlineFont.source"google" or "local"Where store-shots fonts add gets it from. Default: "google".
brand.headlineFont.weightslist of whole numberThe weights downloaded; headlines use the heaviest a headline font lists. Default: [400, 600, 700].
brand.headlineFont.fallbackslist of textExtra families tried after family, in order (must be local: fonts add). Bundled fallbacks are appended automatically. Default: [].
brand.backgroundobject, optionalProject-wide default background; screens inherit it unless they override (backgroundImage "none" opts out of a texture).
brand.background.backgroundtext, optionalAny CSS background: a colour, a gradient, several layered.
brand.background.backgroundImagetext, optionalOver the background: "asset:<file in store/assets>", "pattern:<waves, dots, grid, lines, zigzag, rings, crosses, checker or noise>", or "none".
brand.background.patternColortext, optionalLine colour of a pattern (any CSS colour; noise ignores it).
brand.background.patternScalenumber, optionalSize of a pattern's tiles, 0.25 to 4 times the default.
brand.background.spantrue or false, optionalStretch the project-default background across the whole screenshot strip (each screen shows its slice).
brand.primarytextThe brand colour: the default background, and Full Bleed Card's card. Default: "#111111".
brand.onPrimarytextThe text colour on primary. Default: "#FFFFFF".
brand.accenttext, optionalColour for the eyebrow and caption (a sub-line in a second colour); default: the text colour.
outputobjectHow the files are written.
output.format"png"The file format; PNG only for now. Default: "png".
output.backgroundColortextThe colour transparency is flattened onto, since the stores refuse alpha. Default: "#FFFFFF".
output.cleanBeforeRendertrue or falseA full run deletes the files of the last run that are no longer planned. Default: true.
validationobjectHow strict the checks are.
validation.strictTranslationstrue or falseA missing translation is an error (true) or a warning (false). Default: true.
validation.failOnOverflowtrue or falseText that overflows at its smallest allowed size is an error (true) or a warning. Default: true.
validation.failOnAlphatrue or falseA rendered file with transparency is an error (true) or a warning. Default: true.
validation.failOnTextOverlaptrue or falseText overlapping the device shell is a warning by default (designers do it on purpose); true makes it an error. Default: false.
validation.screensPerTargetobjectHow many screenshots each device and language should have (Apple takes 1 to 10).
validation.screensPerTarget.minwhole numberFewer is reported. Default: 3.
validation.screensPerTarget.maxwhole numberMore is reported. Default: 10.
metadataobjectThe store text in fastlane/metadata.
metadata.managetrue or falseThe tool edits and checks the store text; false leaves it to you. Default: true.
metadata.fieldslist of enumThe fields Listing shows and readiness requires. Default: [...METADATA_FIELDS].
presetsmap of map of anyNamed override presets applied to screens from the editor ("apply preset").
captureobjectAutomated capture: how to put the simulator into a known state (plan section 7.5).
capture.statemap of anyAsyncStorage entries written into the simulator's app container before each capture run, so screens never show an empty streak or onboarding. Values are stored as JSON; strings are written through unchanged. \{today\} and \{today-N\} in any string resolve to YYYY-MM-DD at run time, which keeps a seeded streak from going stale between runs.
capture.storageDirtextFolder under Library/Application Support/<bundleId> that holds AsyncStorage. Default: "RCTAsyncLocalStorage_V1".
capture.appleLanguagesmap of textApp Store locale -> iOS AppleLanguages value, when the two differ.
capture.settleSecondsnumberSeconds to wait after opening a deep link before the screenshot. Default: 2.
capture.languageSettleSecondsnumberSeconds to wait for SpringBoard after switching the simulator language. Default: 8.
scenesobject, optionalThe art pipeline behind store/assets: Blender renders and their post-processing, in order.
scenes.blendertext, optionalPath to the Blender binary (default: $BLENDER, /Applications/Blender.app, or blender on PATH).
scenes.stepslist of objectThe steps, in order.
scenes.steps[].idtextThe step's name, for scenes render \<step\> and needs.
scenes.steps[].blendertext, optionalRun as blender -b --factory-startup with this script; its arguments follow --.
scenes.steps[].pythontext, optionalRun with python3 -I; its arguments are the usual sys.argv[1:].
scenes.steps[].argslist of text\{root\}, \{work\} and \{assets\} are replaced with absolute paths. Default: [].
scenes.steps[].inputslist of textFiles or folders that re-run the step when they change (the script's folder always does). Default: [].
scenes.steps[].outputslist of textFiles the step writes; a missing one re-runs it. Default: [].
scenes.steps[].needslist of text, optionalEarlier steps whose output it reads: when one runs, so does this. Default: every earlier step.
fastlaneobjectThe app's own fastlane lanes the tool may run. It never runs one that builds or submits.
fastlane.enabledtrue or falseFalse turns off the lanes and the credentials check. Default: true.
fastlane.lanesobjectThe lane names, as \<platform\> \<lane\>.
fastlane.lanes.validatetextChecks the store text against the limits. Default: "ios validate_metadata".
fastlane.lanes.metadatatextUploads the store text. Default: "ios metadata".
fastlane.lanes.screenshotstextUploads the screenshots. Default: "ios screenshots".

store/manifest.json

The screens, in order, and the named pages.

screens[]

KeyTypeWhat it is
idtextThe screen's name: lowercase letters, digits and dashes. It names its copy, captures and files.
orderwhole numberIts position on the default page, from 1.
enabledtrue or falseOn the default page; false keeps it for other pages, or for the header and event pictures. Default: true.
templatetextThe template id: hero-top, split-caption, full-bleed-card or feature-graphic.
sourceobjectWhere the screen's capture is.
source.filePatterntextInterpolates {order} {id} {locale} {device} {target}. Relative to raw/<device>/<locale>/. Default: "{order}-{id}.png".
source.localizedtrue or falsefalse: use the default-locale capture for every locale. Default: true.
source.deepLinktext, optionalDeep link the capture helper opens before screenshotting (capture --all), e.g. "braele://session/478".
targetslist of text, optionalOnly for targets listed here; default: all configured targets.
panoramaobject, optionalPanorama: render one artwork slices screenshots wide and cut it into consecutive files (order, order+1, ...). The following order numbers are reserved for the slices.
panorama.sliceswhole numberHow many screenshots wide: 2 or 3.
overridesmap of anyThe layout and background the inspector sets; see screens[].overrides below.
layerslist of object (by "type")Extra image/text elements composited over the template. Text layers read content field <layer id>.
appearance"light" or "dark", optionalWhat the capture shows. Apple suggests one Dark Mode screenshot when the app supports it; readiness looks for it.

screens[].overrides

What the inspector's Layout and Background tabs set. Every template takes these; Full Bleed Card adds cardPosition and cardColor.

KeyTypeWhat it is
backgroundtext, optionalCSS background colour/gradient; default derives from brand.primary.
backgroundImagetext, optionalBackground image layered over background: "asset:<path under store/assets>" (e.g. "asset:backgrounds/waves.png", cover-fitted) or a built-in pattern: "pattern:waves" | "pattern:dots" | "pattern:grid".
patternColortext, optionalLine colour for built-in patterns (any CSS colour; ignored by "noise").
patternScalenumber, optionalTile size multiplier for built-in patterns.
screenshotScalenumber, optionalDevice width as a fraction of the canvas width.
screenshotOffsetXnumber, optionalHorizontal nudge of the device, fraction of the target width (negative = towards the start side). Panoramas may go up to +-3.
screenshotOffsetYnumber, optionalVertical nudge of the device, fraction of canvas width (positive = down).
deviceTiltnumber, optionalRotation in degrees.
textWidthnumber, optionalText column width as a fraction of the usable width (1 = full width).
textSide"start" or "end", optionalWhich side the text column hugs when narrower than full width (logical: start = left in LTR).
textOffsetXnumber, optionalHorizontal nudge of the text block, fraction of the target width (mirrored in RTL).
textOffsetYnumber, optionalVertical nudge of the text block, fraction of canvas width (positive = down).
textOffsetX2number, optionalSlide 2's text, across (a wide screen's slides each have their own).
textOffsetY2number, optionalSlide 2's text, down.
textOffsetX3number, optionalSlide 3's text, across.
textOffsetY3number, optionalSlide 3's text, down.
textAlign"start" or "center" or "end", optionalText alignment (start = left in left-to-right languages).
textColortext, optionalText colour override (any CSS colour); default brand.onPrimary.
accentColortext, optionalEyebrow and caption colour (any CSS colour); default brand.accent, else the text colour.
shell"dark" or "light" or "none" or text or map of "dark" or "light" or "none" or text, optionalNeutral shell ("dark" | "light" | "none") or an official device frame: "frame:<name>" (see store-shots frames list). Either one value for every target, or a map keyed by target family ({ "iphone": ..., "ipad": ... }) when the same screen needs a different frame per device.

screens[].layers[]

A layer is an image (type: "image") or a line of text (type: "text"): image and text share id, x, y, width, rotate, opacity and targets.

sets[]

KeyTypeWhat it is
idtextThe page's name in the tool: lowercase letters, digits and dashes.
kind"custom" or "ppo""custom" for a custom product page, "ppo" for an optimization test treatment.
nametext, optionalThe page's or treatment's name in App Store Connect, for your reference.
screenslist of textScreen ids, in the order the set shows them.
deepLinktext, optionalCustom product pages: where the app opens when installed from this page (a URL or the app's own scheme).
appIconNametext, optionalOptimization treatments: an alternate app icon in the shipped binary (its name in the asset catalog).
experimenttext, optionalOptimization treatments: the experiment (test) it belongs to; treatments with one name share it.
ascIdtext, optionalApp Store Connect's id for this page or treatment, written when the tool first uploads it. An editor sends "" to unlink it (the page was deleted there, or the test ended).

store/content/<locale>.json

KeyTypeWhat it is
localetextThe language this file is for, as in the file name.
direction"ltr" or "rtl", optionalRight to left mirrors the layouts; default: from the language.
screensmap of map of text or nullscreen id -> field -> text (null = intentionally empty)
setsmap of object, optionalset id -> that page's or treatment's own text in this locale.

sets.<page>

KeyTypeWhat it is
promotionalTexttext, optionalShown above the description on this page (custom product pages; 170 characters).
keywordslist of text, optionalKeywords from the app's keyword field that lead search to this page (custom product pages).
screensmap of map of text or nullscreen id -> field -> text, over the default page's copy for that screen.

On this page