Café Arona: a Shopify website for a family business
Introducing the business now and preparing for day-to-day management.
A family in Sherbrooke hired me to work on the website for Café Arona, a business preparing to introduce Cameroonian coffee in Québec. They already had a story, a visual identity and people behind the project. The brief was to give those elements a clear place online and a content structure the team can manage.
The website presents the company’s history, values, team and articles supplied by the client. Its theme also contains catalogue components: collections, product pages, option selection, search and a cart. Text and images sit within sections designed to be editable through Shopify.
My work involves migrating the existing Webflow site to Shopify, organizing its content and developing the theme. At its current stage, Café Arona is an informational website in development, with sales not yet open and the Shopify handover still ahead. This is what is built, how the parts work together and the principles behind managing them.
Introducing the people behind the coffee#
Café Arona’s story connects Cameroon and Québec through the people building the business. The history, values and team pages give visitors room to understand that connection.
I organized the content into formats with different purposes. One page tells the story of the business. Another presents its values. The team page brings together a group photo, individual portraits and introductions. A blog provides a place for articles supplied by the client alongside the more permanent pages.
Visitors can understand who is behind the business before exploring its products. They can spend time with an article or find a way to contact the team. That journey has a purpose of its own: the website introduces a business and its context before online sales open.
An existing identity, editable content#
The existing colours, photographs and typography provide the starting point. The migration carries that identity into a Shopify theme, with pages the client will be able to update from the administration area.
The relationship between presentation and management guides the work. A heading needs both a place in the layout and an understandable place to edit it. A photograph needs to work on a small screen and be replaceable without rebuilding the page. A product page needs to present coffee information and read it from fields that can be kept current.
Shopify brings those content needs together with the functions intended for the future store. The theme already includes collections, product pages, search and a cart. Their presence describes the work built so far; it does not mean that the final catalogue has been loaded or sales have opened.
The expandable sections below let readers choose their level of detail. Each explains one part of the website: its purpose, how it works and what to check when changing it.
What is in place and what comes next#
Café Arona has a development website, presentation pages and a theme connecting editable content, product pages, variants and a bilingual structure. The technical choices serve practical tasks: knowing where to change information, where that change appears and what to check afterwards.
The next stage provides for integrating the final catalogue, validating the journeys intended for sales and handing the website over with documentation and training. Those additions will use the structure already built.
The website uses a Shopify Liquid theme built from the Skeleton foundation. Liquid brings Shopify-managed content together with the theme’s elements. The browser then receives an HTML page, its CSS presentation and the JavaScript behaviour it needs. This organization fits the brief: an informational website whose content and future catalogue are managed in the same administration area.
The theme has several layers. A shared layout places the header, main content and footer. JSON templates specify which sections make up a family of pages. Sections provide visible elements such as the home-page banner or team presentation. Smaller reusable components handle shared details, such as a button or a price.
Each layer has a responsibility. Changing a shared button’s styling can affect several pages. Changing a button’s wording in a section changes that section’s content. Confusing the two would either spread exceptions through the code or require development for a straightforward wording correction.
What the editor makes editable#
Sections declare their settings: text, images, links and options provided by the theme. The following minimal illustration was written for this article and is separate from the project’s code. It represents a heading and destination intended to be editable:
{
"name": "Introduction",
"settings": [
{ "type": "text", "id": "intro_title", "label": "Titre" },
{ "type": "url", "id": "intro_destination", "label": "Lien" }
]
}In this example, intro_title and intro_destination are stable identifiers. The client works with the labels shown in the editor. They can change content without having to find a line of HTML.
The visual framework remains defined by the theme. Adding a new interaction or a new family of pages still requires development. The intended independence concerns recognizable tasks: correcting a sentence, replacing an image, updating an introduction or changing where a link leads.
When a template is shared#
If two pages use the same template, changing that template’s composition can affect both. Before editing, the person making the change needs to distinguish page-specific content from shared structure. The handover documentation should explain that scope.
A short editing map makes the distinction practical: biographies in the team section, articles in the blog, coffee information in the catalogue and custom fields. The right place depends on the type of information, not simply where it appears on the screen.
A catalogue is more than a collection of cards with names and prices. Each object needs a clear meaning. A product holds a shared presentation. A variant identifies a specific combination of selectable options. A collection groups products for navigation. A custom field describes an additional characteristic.
For Café Arona, the collection structure provides for green coffee, roasted coffee and merchandise. That gives the project’s categories a place; it does not announce that all those products are available. Final content and publication states must follow the client’s confirmed decisions.
Description, option or inventory data?#
A coffee’s origin and tasting notes describe the product. A package size or preparation can distinguish a variant. An available quantity refers to particular units. Mixing these details into a single paragraph can make a page look complete while leaving its management data incomplete.
The theme has an information panel that displays custom fields, treating single values and lists differently. Tasting notes can therefore appear as several items. This Liquid illustration is independent of the project code:
{% for tasting_note in coffee_notes %}
<span>{{ tasting_note | escape }}</span>
{% endfor %}Here, coffee_notes represents a list, and tasting_note one note at a time. The escape filter displays each value as text rather than HTML markup. The example shows how a shared presentation can receive different information. It does not decide which flavours describe the coffee: those values must come from confirmed products and approved writing.
Not every field belongs in public. Information intended for display needs to be separated from internal working notes. Catalogue onboarding must therefore include a check of what actually appears on the product page, not only the form used to enter it.
A worked example of combinations#
Consider a fictional example, unrelated to Café Arona’s final package sizes: two sizes, A and B, and two preparations, whole bean or ground. That gives 2 × 2 = 4 possible combinations. If only three have been approved, the fourth should not appear as a variant that is merely sold out. It is not yet a confirmed offer.
The distinction also matters for images and prices. Each selection must retain the correct variant identifier, show the corresponding information and avoid silently reusing another option’s details. A cart quantity applies to the selected variant, not the coffee’s general name.
This structure separates the components already built from the data they display. A confirmed catalogue can be added without rebuilding the presentation of every product page. The editing framework stays consistent, while values and variants belong to each product.
An empty collection is different from a search with no results#
A collection organizes access to products. Its template displays a grid, filtering controls and pagination when needed. It also provides for two situations that look similar but need different explanations: the collection contains no products, or the chosen filters produce no results.
In the first case, visitors need to understand what the section is for and where to continue. In the second, they need to understand that their selection limits the results and be able to change it. Using the same message for both could suggest that a filter made the catalogue disappear, or that changing options can fix an empty section.
The theme represents this distinction through shared state messages. Their visual structure stays consistent while the heading, explanation and action match the situation. This is useful reuse: the component handles presentation, and the collection’s data determines the message’s meaning.
Reviewing a collection therefore includes its normal display, pagination and states without content. It also includes links to product pages. Visitors move between several views of the same catalogue; consistency extends beyond an isolated product card.
A visible product is not necessarily purchasable. A page may introduce an upcoming offer. A variant may exist without being available. A quantity may be insufficient for a request. These situations need different messages and actions.
The theme prepares an initial state on Shopify’s side when the page is generated. JavaScript in the browser then responds to option choices: it finds the corresponding variant and updates the visible information. The important point is consistency between those moments. A rule applied when the page loads must continue to apply after a selection changes.
Making the rule explicit#
The following model was written for the article to explain that distinction. It represents a rule to verify before opening sales; it is not the project’s deployed code:
function purchaseState({ salesEnabled, productApproved, variant }) {
if (!salesEnabled || !productApproved) return "information";
if (!variant) return "unavailable";
return variant.available ? "available" : "sold_out";
}The model first checks whether sales and the product are authorized, then whether the variant exists, and finally whether it is available. The identifiers are illustrative. What matters is the order of reasoning: available stock should not override a decision to present a product for information only.
Four situations produce different expectations:
- Sales are not open: the page can inform visitors without offering a purchase.
- The product is confirmed but the combination does not exist: explain that the selection is not offered.
- The variant exists but is unavailable: show that state without presenting it as a website error.
- The variant is available within an authorized sales journey: allow the visitor to proceed, subject to the cart’s final validation.
To verify this behaviour, the same rules need to be checked on initial display, after an option changes and when an addition is requested. A disabled button in a screenshot cannot demonstrate that entire journey. The useful scenario is a changing selection: its message, variant and permitted action need to stay consistent.
A request and its response#
The browser sends an add-to-cart request and receives a response from Shopify. Until the response arrives, the interface needs to distinguish a request in progress from a confirmed addition. A quantity failure and a network problem call for different explanations.
The addition itself also needs to be distinguished from refreshing the cart display. If the addition succeeds but the counter does not refresh, automatically retrying could add the product twice. Visual feedback should follow what the system has actually confirmed.
This makes validation practical: try a variant change, a missing combination, a rejected quantity and a slow response. Those behaviours cannot be checked by looking only at the page in its normal state.
Displayed availability also belongs to a moment in time. Stock can change while someone chooses options. Browser-side checks help guide that selection, but a request rejected by the service must remain rejected even if the button was active a moment earlier. The message needs to help the visitor resume the journey without treating the earlier display as an order confirmation.
The theme can display a price, availability and several options. For those elements to make sense, their data needs to describe the same variant and product state. The question extends beyond appearance: what is being counted, who confirms the information and which value is used for display?
A physical unit count, reserved quantity and availability are not interchangeable. An approved description and photograph do not replace a count. Conversely, an available quantity does not confirm the commercial wording or delivery terms.
The catalogue intake record#
The catalogue intake model provides for one row per variant intended for sale. That row needs to connect its name, options, size, approved price, image, quantity and state. It should also identify who approved the information. The examples here contain none of the client’s operating data.
Missing information remains unconfirmed. Replacing it with a plausible value would erase the distinction between a layout example and a real offer. The same rule applies to translations and flavour descriptions.
A fictional calculation to explain the check#
Imagine, solely to illustrate the method, 40 physically counted finished units, including 6 reserved units and 2 that cannot be sold. If those categories are distinct and included in the original 40, the remaining quantity would be 40 − 6 − 2 = 32. This calculation does not describe any Café Arona inventory.
The point is to establish definitions. If a system already reports availability after reservations, subtracting the six units again would introduce an error. Before reconciling a spreadsheet with Shopify, each column needs a clear meaning, a corresponding variant and a time for its count.
Integrating in controlled stages#
The catalogue can first be integrated through a small representative set: a product page with its options, fields, images and translations. Previewing it will show what that structure actually produces. Once the entry pattern is confirmed, the remaining pages can follow the same framework.
This method concerns the quality of incoming data. The presentation architecture is already built; the review follows relationships between products, collections, variants and quantities. It checks the result of data entry without confusing its appearance with its validity.
French is the project’s primary language. The theme also contains language files and a switching mechanism for English. That foundation prepares for bilingual use, but several kinds of content need to remain consistent.
Interface text includes navigation labels, buttons and success or error messages. Editorial content includes introductions, biographies and articles. Product information includes descriptions, option names and custom-field values. Updating one family does not automatically update the others.
The theme’s switcher uses Shopify’s localization form. Its role is to request a change among the available languages. Page addresses and website actions then need to continue in the correct language context. A translated button leading into the wrong journey would leave the work incomplete.
Starting from a content change#
If the client changes a French description, the English review needs to check the same information, not just whether the sentence reads well. A removed tasting note, changed package size or revised availability condition needs an accurate equivalent.
A field’s label also needs to be distinguished from its value. Translating “origin” does not necessarily translate the content that follows it. The theme reads data that Shopify can localize, so editing needs to check both the label presented to the reader and the value displayed.
Reviewing a complete journey#
The planned review follows a page in both languages, then its links, messages and less common states. It includes longer content that changes the layout and errors that are not visible when the page first loads.
That approach defines bilingual delivery through reviewed content and journeys. English files in the repository are not enough to establish that every client update has been translated. Bilingual management connects the changed content, its translation and the journey in which it appears.
Café Arona’s identity uses contrasting colours, distinctive typography, photographs and a video banner. The task is to retain that presence while leaving room for content and interaction.
The team page is a useful example. The group photograph places people together. Individual portraits allow visitors to choose a person’s introduction. At a narrow width, the composition needs to remain readable without asking visitors to navigate a grid designed only for a large screen.
The theme has shared behaviour for the tabbed interfaces used by the team and values sections. It connects the selected item to its content panel and handles keyboard commands. The reuse concerns a shared behaviour; the two sections retain their own content and presentation.
Focus is part of the journey#
Seeing a selected portrait and knowing where keyboard focus is located are different pieces of information. Arrow keys, the start and end of a list, and panel visibility need to work together. The project’s logic tests cover index movement and key interpretation, among other rules. They do not replace using the actual page with a keyboard.
The same distinction applies to an error message. It needs to appear in the right place and be perceivable by someone who is not following only visual changes. The theme includes announcement regions, but those regions need to be checked alongside the complete behaviour.
Images, video and page weight#
Main images and small thumbnails serve different purposes. The theme requests appropriate sizes and reserves some display dimensions. The banner video has a poster image, and its behaviour takes a reduced-motion preference into account. These mechanisms are present in the code; their presence alone does not establish a measured performance result.
An image that looks sharp on a large screen may be heavier than the intended use needs. A successful desktop crop may cut off a face on mobile. The review needs to consider what is actually visible, the image sizes downloaded and the browser’s behaviour.
The two home-page views selected for this presentation come from a browser showing the development storefront. The mobile view represents a browser width, not a test on a physical phone. They document the interface at this stage. They do not establish validation of every screen size or page.
For the client to maintain the website, they need to know what they are changing and what to inspect afterwards. Replacing an image, changing a shared structure and adding a variant have different scopes.
The proposed handover workflow starts by identifying the content, the person approving it and the expected result. For layout changes, a theme copy provides a preview before publication. For a product or article, the content itself also needs attention: copying a theme does not automatically duplicate all store data.
Example: replacing a team photograph#
The task goes beyond selecting a file. The correct image, permission to use it, alternative text and crop all need confirmation. The next step is to preview the complete page: group photo, portraits, nearby writing and narrow layout. If the caption changes, its English version joins the same review.
This journey shows the value of well-defined fields. The person editing should be able to change the intended content without touching tab behaviour. Development becomes relevant when the request changes the structure or interaction.
Example: preparing a product page#
A representative product page makes it possible to follow the cycle: confirmed data, entry, field display, option selection, language and availability state. A missing option needs the intended result. A missing photograph should not pass unnoticed merely because the rest of the page works.
The project’s automated tests cover specific cart and tab-navigation functions. They help check precise rules, such as handling an index or classifying an error. They do not establish that photographs, data, translations and all journeys work correctly together.
A rollback that matches the change#
Keeping the previous theme provides a return point for a theme change. For an incorrect description or quantity, switching back to an earlier theme does not automatically restore the data. The procedure therefore needs to preserve what was actually changed.
The handover should include a practical exercise with the client: make a simple change, preview it, have it checked and find the recovery steps if the result differs from what was expected. The exercise checks a practical management capability beyond the presence of an edit button.
The intended handover result is a website the client can manage within the agreed scope. Access alone is not sufficient. Confirmed content, a map of responsibilities and understandable maintenance tasks are also needed.
The client retains decisions about products, prices, quantities and writing. One person may handle routine updates while another approves them. Code changes, new behaviours and structural work call for a separate technical responsibility. A support agreement needs to define the scope of interventions and each person’s responsibility.
Ownership and continuity#
The handover inventory should cover the store, domain, required access, content, media, translations, apps and documentation. It needs to establish who owns the accounts, who can recover access and who approves a significant change. No credentials or private details need to appear in a case study to explain that requirement.
The Shopify procedure depends on the exact store type and its situation at handover. A development environment’s name does not establish what can be transferred. That check belongs in preparing the transfer or, if needed, an authorized migration. The check concerns actual ownership and account rights, not the names of the accounts.
Proportionate maintenance#
Routine maintenance can cover outdated content, images to replace, links to check and translations to revise. Technical review will be needed after changes affecting the theme or apps. Frequency should follow actual activity and the support agreement.
For each intervention, a short record is useful: what changed, why, who approved it and what was checked. That record helps another person take over and keeps knowledge from depending entirely on the developer’s memory.
A Webflow-to-Shopify migration for Café Arona, a family business in Sherbrooke. Editable content, theme architecture, catalogue structure and bilingual journeys.
Let's build somethingthat moves.
Database, pipeline, dashboard, website: wherever it's stuck, that's where we start.