Skip to content

Create a custom page

Goal: a “Ramadan offers” landing page at /custom/ramadan-offers, then the same layout on a store page the merchant can edit and translate.

You need: a store with a few products, and the live theme (or a copy) open in the code editor.

Custom pages are Liquid files in your theme’s custom_pages/ folder. Each one is a page of its own, drawn inside the theme layout, and merchants can pick it as the layout of any page in Storefront › Pages. See Custom pages for everything they can do.

  1. Add the file. In the code editor’s file tree, open the actions of the custom_pages folder, choose Add file, type ramadan-offers and choose Create file.

  2. Replace the starter with this page.

    custom_pages/ramadan-offers.liquid
    <section class="page-width ramadan-offers">
    <h1>{{ custom_page.title }}</h1>
    {%- if custom_page.settings.intro != blank -%}
    <div class="rte">{{ custom_page.settings.intro }}</div>
    {%- endif -%}
    {%- if page -%}
    <div class="rte">{{ page.content }}</div>
    {%- endif -%}
    <ul class="ramadan-offers__grid" role="list">
    {%- for product in collections.all.products limit: custom_page.settings.limit -%}
    <li>
    <a href="{{ product.url }}">
    {%- if product.featured_image -%}
    {{ product.featured_image | image_url: width: 600 | image_tag: sizes: '(min-width: 750px) 25vw, 50vw' }}
    {%- endif -%}
    <span class="ramadan-offers__title">{{ product.title }}</span>
    </a>
    <span class="ramadan-offers__price">{{ product.price | money }}</span>
    </li>
    {%- endfor -%}
    </ul>
    </section>
    {% stylesheet %}
    .ramadan-offers__grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr)); gap: 1rem; padding: 0; list-style: none; }
    .ramadan-offers__grid img { width: 100%; height: auto; border-radius: 8px; }
    .ramadan-offers__title { display: block; margin-block-start: .5rem; }
    {% endstylesheet %}
    {% schema %}
    {
    "name": "Ramadan offers",
    "layout": "theme",
    "seo": { "title": "Ramadan offers", "description": "Our picks for Ramadan, delivered before Iftar." },
    "settings": [
    { "type": "richtext", "id": "intro", "label": "Introduction", "default": "<p>Our picks for Ramadan, delivered before Iftar.</p>" },
    { "type": "range", "id": "limit", "label": "Products", "min": 2, "max": 12, "step": 1, "default": 8 }
    ]
    }
    {% endschema %}
    • custom_page has the page’s title and the settings from its schema.
    • page is set only when a store page uses this file (step 5), so the page’s own text shows there.
    • "layout": "theme" draws the page inside layout/theme.liquid, with the header and footer. Use "none" for a bare page.
    • seo sets the title and description of /custom/ramadan-offers.
  3. Save with Ctrl + S.

  4. Open the page. Visit https://<your-store>/custom/ramadan-offers, or choose Preview in the editor. You see the heading “Ramadan offers”, the introduction and up to eight products with their prices. The page is also added to the store’s sitemap.

  5. Attach it to a store page. In admin, go to Storefront › Pages and choose Add page. Enter the title Ramadan and some text, such as Iftar boxes ship daily until the last night of Ramadan. Under Theme template, choose Custom page: ramadan-offers, make the page visible and save.

    Visit /pages/ramadan. The same layout shows, with the page’s title as the heading and its text under the introduction. A store page gives the merchant a translatable title and handle, SEO fields, and visibility dates, while the layout stays in the theme.

  6. Link it from the menu. In Storefront › Navigation menus, open the main menu and add a link. In the link picker, Custom pages lists every file in custom_pages/; choose Ramadan offers. The link is stored by name, so it keeps working if the store moves to another domain or language.

  • /custom/ramadan-offers: the landing page, with its settings’ defaults.
  • /pages/ramadan: the same layout with the merchant’s title and text, in every published language.
  • Add a section to the page: {% section 'newsletter' %} renders a section file in place.
  • Read Custom pages for routing, links and what happens when a file is renamed or deleted.

Was this page helpful?