Project Summary

This client project is a business website for Shin Yuan, a taiwanese frozen foods producer based in Brisbane, Australia. The website bridges the gap between traditional community-based group buying (团购) and modern digital experiences.
Tech Stack
- Framework: Astro
- CMS: Sanity.io
- Styling: Tailwind CSS
- Deployment: Vercel and CloudFlare Registrar
This project was the first time I used Astro and Sanity CMS. Using Astro showed me it's advantages in simple static business websites, providing a super fast and lightweight experience for the user and developer. After experimenting with Sanity, I used it in this project to allow the business owner to easily update the website without any technical experience.
The Business's Problem
Shin Yuan operated primarily through a Facebook reselling group. This is common in the Taiwanese community, where a group of buyers can buy products in periodic rotations. Each rotation would offer a different set of products at a bulk-discounted price.
Originally, products were shared as a static list in a Facebook group post. Whilst straightforward, the manual posting process led to high friction:
- Customers struggled to visualize items without product images or descriptions, reducing their confidence in the purchase.
- Customers didn't have access to further information about the products (like ingredients or allergens) to make informed decision.
- The business owner spent excessive time answering repetitive questions related to products and orders
The Solution
I built a dynamic catalog website that allows the business to showcase its weekly rotating inventory with professional clarity.
-
Dynamic Catalog System: Utilizing Sanity CMS, I built a backend that allows for easy updates to the weekly rotation, automatically updating the frontend. After adding all the products to a product index, the business can select the weekly products in just seconds.
-
UX-First Design: Instead of a complex checkout, I designed a "low-friction" path that directs users to the existing Facebook ordering flow, respecting the current business model while enhancing the discovery phase. This decision was made at the business's request, and opens the possibility of migrating the website to an online ordering/purchase model later on.
-
Trust & Clarity: Strategically placed content like FAQs and customer reviews address uncertainty at the key points of decision. Combined with clear primary buttons, UX strategies create intuitive customer flows with reduced user friction.

The Measurable Impact
Moving from a simple Facebook text list to a dynamic website transformed the customer journey. By providing organized categories, high-quality visuals, and detailed product info, we answer customer's uncertainties, reduced decision fatigue, and streamlined the flow of purchases.
- Reduced Decision Fatigue: By categorizing products (e.g., "Weekly Specials" vs. "All-time Favorites"), users no longer had to scroll through an unstructured wall of text. This decreased the cognitive load and helped them find what they wanted in seconds.
- Operational Efficiency: The proactive integration of FAQs at the point of sale meant fewer questions about the products and ordering process. For the business owner, this reclaimed hours previously spent on manual customer support, by guiding users to the information they could need.
- Higher Perceived Value: Transitioning from a text list to a high-performing web experience instantly elevated the brand's professional image. Customers aren't just buying food; they are buying from a business they trust, and a polished UI/UX is one of the strongest signals of that trust.
Project Management Growth
This project served as a milestone in my development as a solo freelancer. Managing the end-to-end lifecycle has significantly bolstered my confidence and proficiency in taking up client projects.
- Scoped Delivery: I learned to prioritize high-value features (like the FAQ system and the CMS-based catalog) over unnecessary complexities.
- Client Communication: Translating business needs into technical schemas in Sanity taught me how to build tools that are as easy for the owner to use as they are for the customer.
Technical Breakdown
Sanity CMS is used for the catalog management. The Product tab includes the full products list. Each product includes the following details:
Product Name
Price ($)
Discount and Discount Price ($)
Quantity (g)
Food Category (noodles, side dishes, etc)
Tag (new, popular)
Product Images
Product Options/Variants
Product Information (description, ingredients, etc)With the products defined, selecting the weekly products is simple. The Weekly Products tab lets you select any of the existing products and publish the changes immediately.

In the product listings, the state is updated by checking whether the current product matches any weekly product. The products result array is mapped against the weekly products array to check if the product IDs match, and returns a isWeeklyProduct boolean.
export async function getStaticPaths() {
const allProducts = await sanityClient.fetch(
`*[_type == "product" && defined(slug)]`
);
const weekly = await sanityClient.fetch(
`*[_type == "weekly" && defined(products)][0]{products[]->{_id}}`
);
const weeklyProductsIds = new Set(
weekly?.products?.map((product: any) => product._id) || []
);
return allProducts.map((product: any) => ({
params: { product: product.slug.current },
props: {
product,
isWeeklyProduct: weeklyProductsIds.has(product._id),
},
}));
}Available weekly products will show a primary "Order" button, along with a help link on how to order. For items that are not on the weekly rotation, the state is updated to show that the item isn't currently available, along with a help link that details the rotation schedule.
