Skip to content

🛞 Still on the Horizon bus, but I'm having Prettier problems (re: tooling) #1134

@michellepace

Description

@michellepace

Apologies if this is not the right team.

Context: I am using the Shopify Horizon theme Dwell as a starting base to customise for my store.

Solution:

Consistently formatted shopify themes along with published .prettierrc file so that future updates will not be git noisy when I try to merge into my custom theme.

Problem:

Similar to my linting issue here for smoothness of working with Claude Code, I am trying to setup deterministic workflows. This includes formatting. As I will be updating my custom theme when any new Dwell versions release, I have tried my best to define the .prettierrc.yaml file as closely as possible to align with a guess at Shopify settings:

# Prettier — all values match @shopify/prettier-plugin-liquid defaults
# See: github.com/Shopify/prettier-plugin-liquid
# --------------------------------------------------

plugins:
  - "@shopify/prettier-plugin-liquid"

# --- Global Shopify defaults (JS, CSS, JSON, MD) ---
printWidth: 120
tabWidth: 2
useTabs: false
singleQuote: true
htmlWhitespaceSensitivity: css
endOfLine: lf

# --- Liquid overrides (Shopify plugin defaults) ---
overrides:
  - files: ["*.liquid"]
    options:
      singleQuote: false        # HTML attrs: double quotes
      liquidSingleQuote: true   # {{ }} / {% %}: single quotes
      embeddedSingleQuote: true # <script>/<style>: single quotes
      singleLineLinkTags: false
      indentSchema: false

I pulled Dwell into my repo using the CLI, it appeared to add two blank lines to the top of nearly every .liquied file. I noticed this because the same was not true for the Horizon collection https://github.com/Shopify/horizon theme when pulling the repo.

This is verbose, but if anyone ever gets to this "small things can make a massive difference to friction" here my full audit report:


Prettier Audit — Handover

Date: 2026-02-23
Theme: Dwell v3.4.0 (Horizon collection) — unmodified upstream
Status: Audit complete. No files have been formatted yet.


1. Prettier Configuration

All values match @shopify/prettier-plugin-liquid defaults. File: .prettierrc.yaml

Option Value Scope Rationale
printWidth 120 Global Shopify plugin default; wider than Prettier's 80 to suit Liquid's verbose syntax
tabWidth 2 Global Standard Shopify convention
useTabs false Global Spaces throughout
singleQuote true Global (JS/CSS/JSON) JS convention; overridden to false for Liquid HTML attrs
htmlWhitespaceSensitivity css Global Prettier default; respects CSS display for whitespace decisions
endOfLine lf Global Unix line endings
singleQuote false Liquid override HTML attributes use double quotes (class="foo")
liquidSingleQuote true Liquid override Liquid tags use single quotes ({{ 'string' }})
embeddedSingleQuote true Liquid override Embedded <script>/<style> use single quotes
singleLineLinkTags false Liquid override <link> tags not collapsed to single line
indentSchema false Liquid override {% schema %} JSON not indented relative to tag

2. Step 1 — Full Repo Audit (all file types)

Command: npx prettier --check .

208 files failed the check, broken down by extension:

Extension Count
.liquid 146
.js 35
.json 17
.md 5
.yaml 2
.css 2
.ts 1
Total 208

3. Step 2 — Liquid Deep Dive (146 files)

Prettier diffs were generated for all 146 .liquid files and every changed line was classified against the .prettierrc.yaml option that caused it.

388 total changed lines:

Category Lines % Config option Description
Blank line removal 251 64.7% (core Prettier) Leading blank lines stripped from top of files
printWidth wrapping 107 27.6% printWidth: 120 CSS transition/animation/background shorthand split across lines
CSS indentation 15 3.9% printWidth: 120 Re-indentation of CSS selectors (:not() lists, etc.)
Other (Liquid plugin) 9 2.3% (plugin) Liquid bracket notation (settings['key']), CSS selector line breaks
embeddedSingleQuote 4 1.0% embeddedSingleQuote: true "radio"'radio' in CSS attribute selectors inside <style>
trailingComma 2 0.5% (default: all) Missing trailing commas in embedded <script> JS

Key insight

~96% of all liquid changes fall into just two buckets:

  • Blank line removal (65%) — cosmetic, no functional impact
  • printWidth wrapping (31%) — CSS shorthand properties reformatted for readability

4. Blank Line Prefix Analysis

Summary table

Dir Total 2-B-P 1-B-P 0-B-P
blocks/ 94 78 13 3
sections/ 39 38 1 0
snippets/ 93 0 0 93
layout/ 2 0 0 2
templates/ 1 0 0 1
TOTALS 229 116 14 99
  • 2-B-P: file starts with exactly 2 blank lines
  • 1-B-P: file starts with exactly 1 blank line
  • 0-B-P: file starts with content on line 1
  • No files had 3+ leading blank lines

Pattern

  • blocks/ + sections/: 87% start with 2 blank lines (116/133)
  • snippets/: 100% start with content on line 1 (0 blank lines)
  • layout/ + templates/: all start with content on line 1

Per-file exception lists

blocks/ — 1-B-P (13 files, start with exactly 1 blank line):

  • _accordion-row.liquid
  • _blog-post-info-text.liquid
  • _header-menu.liquid
  • _inline-collection-title.liquid
  • _media-without-appearance.liquid
  • _product-media-gallery.liquid
  • button.liquid
  • buy-buttons.liquid
  • contact-form-submit-button.liquid
  • filters.liquid
  • footer-copyright.liquid
  • footer-policy-list.liquid
  • payment-icons.liquid

blocks/ — 0-B-P (3 files, no leading blank lines):

  • _blog-post-description.liquid
  • _featured-blog-posts-title.liquid
  • _layered-slide.liquid

sections/ — 1-B-P (1 file):

  • product-recommendations.liquid

5. Shopify Docs Verification

Findings from official Shopify Liquid documentation:

  1. No requirement for leading blank lines in .liquid files — not documented anywhere
  2. Liquid is a literal template engine — blank lines pass through to HTML output, but browsers ignore leading whitespace, so zero visual difference
  3. Shopify's own Prettier plugin (@shopify/prettier-plugin-liquid) is designed to strip these — this is its intended behaviour
  4. {% doc %} tags are documented as needing to be "at the top" of the file, which argues for removing leading blank lines
  5. Whitespace control ({%- -%}) is about cosmetic HTML output, not functional behaviour

Conclusion: removing leading blank lines is safe and expected by Shopify's tooling.


6. Open Question — Format All vs Minimal Diff

Goal: CI-enforced Prettier formatting (pre-commit hook + CI check) as part of pragmatic best practice.

This theme is an unmodified copy of Shopify's Dwell v3.4.0. Future upstream updates will need to be merged in. The central dilemma:

Option A: Format everything now (prettier --write .)

Proposed workflow:

Commit 1: Shopify Dwell theme exactly as downloaded (already done)
Commit 2: `prettier --write .` — format everything (single formatting-only commit)
Commit n: Prettier enforced via pre-commit hook + CI check on all future changes

Upstream update strategy: when Shopify releases Dwell v3.5+, format the incoming upstream code first (prettier --write .), then merge it into the customised branch. This way you compare formatted-to-formatted, avoiding formatting noise in the diff.

Pros:

  • Clean, consistent codebase from day one
  • All 208 files pass prettier --check immediately
  • Future code changes are always clean
  • ~96% of liquid changes are trivial (blank lines + line wrapping) — low risk
  • Upstream merges are clean if incoming code is formatted first (formatted vs formatted)

Cons:

  • Creates a large "formatting-only" commit touching 208 files
  • Requires discipline: must always format incoming upstream updates before merging
  • If upstream formatting is skipped, the merge will contain formatting noise alongside real changes

Option B: Format only files you modify

Pros:

  • Upstream diffs remain clean — unmodified files match upstream exactly
  • Merging Dwell updates is straightforward for untouched files
  • No large formatting commit polluting git history

Cons:

  • Inconsistent formatting across the codebase (some files formatted, some not)
  • prettier --check continues to fail on unmodified upstream files
  • Need to configure CI/tooling to only check modified files

Empirical context for the decision

  • 208 of ~229 files currently fail Prettier (91% of the codebase)
  • 96% of liquid changes are blank line removal (65%) + CSS line wrapping (31%) — these are trivial, zero-risk reformats
  • The remaining 4% (embeddedSingleQuote, trailingComma, Liquid plugin tweaks) are also safe
  • snippets/ files have zero blank line issues — they only fail for CSS/JS formatting within <style>/<script> tags
  • The blank line pattern (2 leading blank lines in blocks/sections, 0 in snippets) appears to be a Shopify build artifact, not intentional

This handover was generated from a Prettier audit conversation on 2026-02-23.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions