쇼피파이 Liquid 템플릿으로 웹 구축하기

하늘·2025년 11월 19일
post-thumbnail

현재 에이전시에 다니고 있는 나는 새로운 프로젝트가 쇼피파이로 구축된다는 말을 듣고 왜 리액트 아니야 빼액!!! 했었다. 전에는 카페24로 이커머스 사이트를 구축했는데, 당시에는 구입한 테마 문제로 FTP를 사용할 수 없어서 웹 에디터로 작업을 해야 했고(ㅠㅠ) Git 같은 버전 관리 대신 최신 작업 5건의 히스토리 관리가 전부였고, 한 명이 작업을 덮어쓰면 다른 사람이 작업한 부분이 다 날아가 버리는 불상사가 있었던 터라, 솔루션을 끼고 하는 구축건에 진절머리가 난 상태였다.

특히 쇼피파이는 쇼피파이를 통해 수익을 낼 수 있는 드랍쉬핑 자료가 대다수였고, 웹 사이트 구축 강의더라도 웹 에디터 GUI로 웹을 꾸밀 수 있는 게 전부였던 터라 AI와 영어로 범벅된 가이드 문서를 따라야 했기 때문에 작업하기가 쉽지 않았다.

요즈음 퍼블리싱 구인 글을 보면 카페24 또는 쇼피파이 구축 경험이 있는 사람을 우대사항으로 뽑는데, 카페24는 그렇다 쳐도 쇼피파이는 경험이 없는 퍼블리셔가 많을 것 같아서, 또 나처럼 난데없는 쇼피파이의 습격에 당황하는 프론트엔드가 있을지도 모른다는 생각에 가이드 겸 프로젝트 회고를 적어 보려고 한다!

쇼피파이로 구축을 하게 된 계기

앞서 말했지만 나는 에이전시에서 프론트엔드 개발자로 근무하고 있다. 자체 서비스가 없어서 고객사가 원하는 대로 작업을 해야 하는데, 외국 이커머스 사이트 구축을 원하는 고객사는 쇼피파이라는 솔루션으로 구축을 원했고.. 이하 생략.

쇼피파이를 내가 어떻게 알어?

Remix로 구축을 할 수 있다고요?

쇼피파이로 웹 구축하는 데에는 두 가지 방법이 있다. Liquid 방식으로 작업을 하거나 아니면 Hydrogen 방식 작업을 하거나.
Hydrogen는 Remix라는 프레임워크로 작업을 할 수 있는데, Remix는 써 보지 않았지만 리액트를 다뤄 본 개발자라면 두 팔 벌려 환영할 만큼 리액트와 정말 많이 닮았다. (애초에 리믹스 창업자가 리액트 라우터 개발자였고 리믹스 자체가 리액트 기반 풀스택 웹 프레임워크이다 보니..)

Liquid 방식은 서버에서 HTML을 생성하는 템플릿 언어로, 쇼피파이가 제공하는 데이터를 이용할 수 있다.

일단 나는 Remix 방식을 밀어붙였다. REST API를 사용하지 않고 GraphQL을 사용하기는 하지만, 마지막 개발 구축이 작년인 만큼(올초에 하나 있었지만 Supabase로 작업해서 그다지 마음에 들지는 않았다..) 오랜만에 리액트를 쓸 생각에 하루하루가 설렜다라고 하면 과언이 아니었다.

나름 공부도 열심히 했다.

하지만..

Liquid 방식으로 채택됐다.

Remix 방식으로 하면 아래와 같은 장점이 있다.

내가 좋아하고사랑하고이제너없으면안되라고외치는 리액트(리믹스)로 작업할 수 있다는 게 큰 장점이고, tailwind CSS를 사용하고(반Tailwind파지만 그래도 인터렉션이 없어서 잘 어울릴 거라고 생각했다), GraphQL도 처음 써 보지만 재미있을 것 같고.. 어쩌고저쩌고 아무튼 장점 100만 개.

그런데 치명적인 단점이 있다.

쇼피파이에서 제공하는 앱을 쓰지 못한다는 것이다

쇼피파이 앱 스토어에 가면 다른 개발자들이 만들어 놓은 앱이 정말 많은데, 그 앱들을 사용하지 못해서 추후 고객사가 추가나 변경을 할 때 큰 제약이 따를 것으로 예상했기 때문이다.

이해는 된다. 이제 하루 빨리 프로젝트가 끝나기를 바라야 한다..

어쨌든 시작

우선 나는 PLP, PDP 같은 제일 중요한 페이지는 작업하지 않았다. 대신에 Metaobject와 Metafield를 요로코롬 저러코롬 북치고 장구치면서 작업을 했기 때문에 이번 글에서는 그 부분에 대해 설명할 생각이다. 아마 PLP, PDP를 작업한 작업자도 앱을 통해서 개발하셨을 것이다.

폴더 구조

└── Shopify/
    ├── assets
    ├── config
    ├── layout
    ├── locales
    ├── sections
    ├── snippets
    └── templates

일단 내가 참여한 프로젝트는 이미 테마를 구입하고 한 상태이므로 완전 날것 그 자체의 테마(Dawn)와는 차이점이 있을 수 있다.

- assets
이미지, 파일, 동영상, 폰트, js 파일 등 여러 에셋을 모아둘 수 있는 폴더다. 안에 폴더를 또 만들면 안 된다.
즉, 페이지별 또는 기능별로 구분하기 위헤

└── assets/
    ├── pages/
    │   ├── notice/
    │   └── news/
    ├── css
    ├── js

이런 식으로 두면 안 된다는 것이다. 나중에 이미지나 파일을 불러올 때 인식을 하지 못한다. 이 단점은 assets 폴더뿐만 아니라 다른 폴더도 공통적으로 적용된다.

- config
setting 파일이 있다. 건드리지 않았다.

- layout
theme.liquid 등 테마에 관련된 파일이 있다. 로직을 수정하지는 않았다. 대신, 공통 CSS를 import 하기 위해 한 줄을 추가했다.
echo 'common.css' | asset_url | stylesheet_tag: preload: true

- locales
다국어 관련 파일이 있다. 필요하면 변경해야 한다. 하지만 변경하지 않았다.

- sections
페이지라고 생각하면 좋다. UI 컴포넌트보다는 더 큰 단위의 컴포넌트라고 생각하면 좋다. 컴포넌트 조각들을 붙일 수도 있고.. 아무튼 그렇다.

- snippets
컴포넌트들을 모아놓는 폴더다.

- templates
어드민과 연결하는 json 파일들이 모여져 있다. 여기에는 sections를 불러와야 한다.

page면 page.페이지이름.json, 블로그 게시판이면 blog.블로그게시판이름.json, 블로그 게시글이면 article.블로그게시글이름.json으로 정해 주어야 한다. 그래야 페이지 또는 블로그를 만들 때 템플릿을 연결할 수 있다.

json 파일은 아래와 같은 규칙을 따른다.

{
  "sections": {
    	"visual": {
          "type": "our-story-visual", // sections 폴더에 만들었던 컴포넌트 파일 이름
          "settings": {}
      	},
        "history": {
          "type": "our-story-history",
          "settings": {}
        },
        "tech": {
          "type": "our-story-tech",
          "settings": {}
        },
        "lifestyle": {
          "type": "our-story-lifestyle",
          "settings": {}
        },
        "product": {
          "type": "our-story-product",
          "settings": {}
        }
  },
  "order": [
    "visual", // 이렇게 리턴을 시켜 주어야 한다
    "history",
    "tech",
    "lifestyle",
    "product"
  ]
}

📄 페이지(또는 블로그 만들기)

페이지 만들기

온라인 스토어 탭 클릭 → 페이지 추가로 만들 수 있다.

제목은 페이지 제목이 된다. 그리고 그게 URL로도 연결된다. 공개 상태는 공개로 두고, 콘텐츠는 안에 들어갈 내용을 적으면 되는데 에디터로 스태틱하게 적는 것보다는 보통 템플릿을 연결한다.

🌟 템플릿 만들기

쇼피파이 앱을 Git에 연결한 다음 IDE로 열어서 작업을 하거나, 테마 편집기 → 코드 편집으로 들어가야 한다. 폴더 구조에서 설명했던 것처럼 template json 파일에 sections 컴포넌트를 연결해 주지 않으면 템플릿에 뜨지 않으니 (되도록) 미리 해 주어야 귀찮지가 않다.

블로그 만들기

블로그는 페이지 생성과는 다르게 콘텐츠 탭에서 게시판과 게시글 두 가지 모두 생성할 수 있다. 생성 방법은 페이지 만들기와 같다.

🔪 Metaobject, Metafield?

쇼피파이 어드민에서는 데이터를 입력할 때 metabjectmetafield라는 것을 사용하는데, 처음에 이 부분을 몰라서 생각보다 많이 당황했다.

metaobject는 쉽게 말해서 어드민에서 데이터를 객체 형식으로 넣는 걸 말하는데, 이 key-value 조합을 직접 만들어야 한다. 그리고 metafieldmetaobject로 만든 객체를 실제 페이지나 블로그에 뿌릴 때 사용된다.

설정 → 메타 필드 및 메타 객체에서 메타 객체 또는 메타 필드를 생성할 수 있다.

우선 메타 객체를 생성해야 한다.

object를 생성하는 일이니 생성하는 건 크게 어렵지 않다. 대신, 이걸 내가 사용하고자 하는 페이지 성격에 맞는 곳에 메타필드를 넣어 주어야 한다.

다시 설정 → 메타 필드 및 메타 객체로 들어와서, 성격에 맞는 페이지를 클릭 후 정의 추가 버튼을 클릭하면 위와 같은 화면이 나오는데, 유형을 메타 객체로 설정하면 된다. 단일은 object type으로 나오고, 값 목록은 array type으로 넣어진다. 즉 여러 개의 메타 객체를 넣을 수 있는 메타 필드도 만들 수 있다는 것이다!

IDE에서 메타 필드 데이터 불러오는 방법

위 폴더 구조에서 말했던 것처럼 page는 page, 블로그 게시판은 blog, 블로그 게시글은 article로 구분된다.

메타 필드를 만들 때 이름을 지정하면 밑에 custom.이름으로 뜨는데, 이 값을 이용해서 값을 불러올 수 있다.

{% assign data = page.metafields.custom.test_metafield.value %}

assign은 변수를 선언할 때 쓰인다. data라는 변수에 page(또는 blog, article, product..).metafields.custom.메타필드이름.value를 넣어서 사용할 수 있다.

값 목록(Array)으로 메타필드를 만들었으면, for문으로 돌려 주어야 한다.

{% for item in page.metafields.custom.test_metafield.value %}

모든 걸 Metaobject로 만드는 게 정답일까?

고객사가 추후 운영할 때 바꾸고 싶은 콘텐츠가 있으면 그때마다 Metaobject를 변경해야 하는데, 이게 생각보다 번거롭다.

하드코딩이 하드코딩이 아니게 되었는데..

정답은 아니다!

쇼피파이는 GUI로 웹 에디터를 제공한다. 아무래도 Metaobject, Metafields를 제어하는 것보다 웹 에디터로 운영하는 게 훨 편할 것이다. 그래서 웹 에디터로 작업할 수 있는 component를 만들 수 있다.

폴더는 sections, 생성한 .liquid 파일에서 schema를 통해 아래처럼 만들 수 있다.

{% schema %}
{
  "name": "Custom Banner",
  "settings": [ // 여기에서 컴포넌트를 조립할 수 있는 세팅을 만들 수 있다
    {
      "type": "select",
      "id": "banner_type",
      "label": "Select Banner Type", // 웹 에디터에서 보여질 Label
      "options": [
        { "value": "icon", "label": "Icon" },
        { "value": "small-image", "label": "Small Image" },
        { "value": "full-image", "label": "Full Image" }
      ],
      "default": "icon"
    },
    { "type": "image_picker", "id": "image_pc", "label": "Image PC" },
    { "type": "image_picker", "id": "image_mobile", "label": "Image Mobile (Optional)" },

    { "type": "richtext", "id": "title", "label": "Title" },
    { "type": "richtext", "id": "description", "label": "Description" },

    { "type": "url", "id": "link", "label": "URL" }
  ],
  "presets": [ // 프리셋을 제공할 수 있다
    {
      "name": "Custom Banner (Icon)",
      "settings": {
        "banner_type": "icon",
        "title": "<p>Icon type example</p>",
        "description": "<p>This is an icon-style feature banner.</p>"
      }
    },
    {
      "name": "Custom Banner (People)",
      "settings": {
        "banner_type": "small-image",
        "title": "<p>Small Image type example</p>",
        "description": "<p></p>"
      }
    },
    {
      "name": "Custom Banner (Full Image)",
      "settings": {
        "banner_type": "full-image",
        "title": "<p>Full image type example</p>",
        "description": "<p></p>"
      }
    }
  ]
}
{% endschema %}

HTML에는 아래처럼 바인딩할 수 있다.

<img src="{{ section.settings.image_pc | image_url: width: 1200 }}" alt="{{ section.settings.title | strip_html | escape }}" />

그러면 섹션을 추가할 때 이렇게 추가할 수 있고,

코드를 수정하지 않아도 웹 에디터에서 간편하게 컴포넌트를 추가할 수 있다.

쇼피파이로 웹 구축을 해 본 회고.. 같은 후기

별로였다. 일단 리액트를 좋아하는 마음을 떠나서, DX가 첫 번째로 별로였고, 아무래도 외국에서 만든 솔루션이다 보니까 한국 이커머스 사이트와는 결이 맞지 않는다고 생각한다. 예를 들어서 한국형 이커머스 사이트에는 문의 게시판이 있는데, 외국은 그것 대신에 문의를 하면(티켓을 끊는 방식) 관리자의 이메일로 메일이 발송되어서 이메일로 티키타카하는 형식인 것 같다. 내가 알고 있는 이커머스 사이트와는 달라서 그 점이 좀 힘들었다.

그리고 Liquid 문법도 개발 인생 3년차에 처음 보는 것들이라서 (Pug가 마지막일 줄 알았지) 익히는 데에 시간이 많이 들었다. 폴더 구조도 마음에 안 들고..

같이 작업한 선임님과 이야기하면 항상 쇼피파이 별로다.. 라는 이야기를 주고받는다. 직접 커스텀하지 못하는 페이지들도 많고, 다수의 앱을 사용해야 하니 앱 숙지 및 커스텀에 대한 시간과 비용도 많이 들었다.

프로젝트 볼륨이 만약 지금보다 더 컸다면 GG 치고 엉엉슨 울었을지도 모르는 프로젝트는.. 홀딩됐다. 내부 사정으로 인해 잠시 홀딩 뒤, 몇 달 뒤 다시 잔여 QA 후 오픈할 예정이라고 하는데 그때까지 내가 쇼피파이를 까먹지 않고 잘할 수 있을지? 만약 내가 회사에 없다면 다른 사람들이 쇼피파이를 잘 다룰 수 있을지 걱정이다.

기회가 된다면 쇼피파이로 만든 작업을 Next.js로 만들어 보고 싶다. 그런데 너무너무 엄두가 안 난다. 언젠가는 하겠지! 나 자신 파이팅!

다시는 쇼피파이 하지 말자고 실장님께 박박 빌어 봐야지..

profile
아무튼 어찌저찌 하고 있습니다.... 🫠

2개의 댓글

comment-user-thumbnail
2025년 11월 21일

별루다 진짜 대충봐도 별루다!

1개의 답글