Page Content Section
Storefront Frontend Series: MERN Stack, GraphQL, and AWS ECS - Part 1

Building frontend assets for online stores, with Figma, Tailwind, Next.js, MERN stack, GraphQL, and more...
This articles delves into several of the important front-end and fullstack development technologies that greatly benefit modern online storefront page development.
The Details
As a developer who has worked in a good amount of application development lifecycles or sprints involving the creation of landing pages, I’ve come to appreciate the need for speed. Landing pages can be resource-intensive because they often comprise large amounts of data. Moreover, much of this data might come from multiple endpoints or domains.
This tends to necessiate making a few or more API calls to several endpoints when designing the data flow for a landing page. Such obviously involves some strategic planning concerning the page layout, components, state management, information architecture, and data provisioning.
Starting with The Design
One of the more common or recurring design motifs for modern online storefronts seems to be the illustrative product card. These collectively give users a comprehensive indication of what an online e-commerce venue has to offer, in a very efficient and user-friendly manner. This is probably why streaming services use cards as the means for keeping their users’ invested in watching. Most developers are very used to dealing with these cards, even as users. So, as a front-end engineer, I’m always enthused about working with card components.
Breaking Ground with Figma
Here are some Figma wireframes for cards that I’ve developed. Yes, we have three designs which could be found in different kinds of online storefronts:
Product Card Examples
- Online Course Product Card
- Finance Digital Asset Card
- Online Film Streaming Feature Card

For the purpose of this article, I selected the online learning course product card and created a pixel-perfect replica of it in plain HTML and CSS. Yes, the ‘vanilla’ template is a good point of departure. Also, I didn’t want to restrict the use of this card to one frontend framework or library. Now, for the CSS styling I decided to use Tailwind CSS, which tends to produce very light stylesheets that certainly push the DRY (Don’t Repeat Yourself) concept, with robust utility class features.
Tailwind Makes a Lean Stylesheet
Here is an example of a simple storefront CTA component that I created for a banner, using Tailwind utility classes. The great thing about this component is that it has NO STYLESHEET module. All the color, spacing, layout, and any breaking point details have been specified with Tailwind utility classes. However, keep in mind that without a specific tailwind.config.js file, the HTML template markup and CSS styles might not render the same in a different project that implements Tailwind.

Rendered CTA Result
So, here is the rendered result (without having to create a stylesheet). Tailwind sorts out all the utilized classes to generate an optimized set of styles that don't repeat. The great part about these utility classes is that they can be fine-tuned for more accuracy. For example, the font size as text-[1.75rem], or margin-bottom as mb-[53px].
Back to the retail cards...
There is one thing about working with these cards. The body or content portions usually require the most revision. In React and Next.js, we have the HOC (Higher Order Component) paradigm which when coupled with the Composition Component concept presents a highly efficient strategy for pushing a component’s reusability. In other frameworks the equivalent would probably be a component factory of some kind.
Let's examine the online course card's apparent structure:
Product Image Container
- Product Image
- Product Rank Indication (best seller, etc.)
- Wishlist Button and Indicator
- Product Type Indicator
- Product Ribbon (text ribbon for extra descriptions or slogans)
- Product Title or Name Block
- Course Credits or Credentials (to be earned)
- Course Scheduling
- Pricing Block
- Ratings Block
To create very a useful online learning course card, I needed to include specific information that would appeal to the potential users. So, as part of the UX research for this interesting front-end R&D series, I visited these online course providers' sites.
Online Learning Providers
- CFTEA
- Coursera
- edX
- LinkedIn Learning
- MindEdge
- Pluralsight
- Udemy
It's Atomic
So, based on what I observed about commercial trends, a well-rounded online learning course card needs to provide some essential information, so that users can make informed decisions while navigating a site, making searches, comparing, contrasting, etc. Also, to ensure that a product card will be as compact as possible some details would be assembled in some form of a popup. For this project, I decided to put the course credits in a pop-up that would be designed as a React Higher Order Component (HOC).
Product Card React Component in Next.js
This is the code for a React component that I created in response to my insights about atomic strategy. It was developed inside a Next.js project.
The Course Product Data Model
In consideration of the intentions regarding entity relationships, the data model was devised as such to allow for more flexibility when using GraphQL queries. This means that the credits, course schedule, course details, and ratings were planned to be brought in using Mongoose Refs (references).
Flexible Http Requests
Now given the data requirements for the course card it’s highly likely that certain fields would need to be trimmed off (hidden), so to speak. Sure, I could just hide those fields in the API, but doing that would require modifying another resource other than the frontend, which leads to more pull requests.
Another option would be selecting specific fields through JSON API Spec’s field selection feature. Here is an example of that approach in a Http request:
Apart from the pre-existing desire to implement GraphQL, I also understood that custom field selections would be easily achievable through querying. At this point, I took some time to further infuse my thought process with Agile Methodology, by defining “the story” for an established portion of what I’ve related regarding the data’s flexibility:
As a
Developer, administrator, or manager
I want
To easily and quickly adjust data fields or relational properties to frontend assets in a way that doesn’t require lengthy adjustments to other resources, such as shipped API codebases or databases.
So that I can
Intuitively customize the appearance of frontend collateral on a landing page (for example) in an online storefront.
Plus, I want the added possibility of receiving real-time updates to dashboard data that represents up-to-date product inventory, sales, or analytics.
Building a GraphQL API
When I started working on this project I was intent on working within a MERN stack (fullstack). For the card design I created I didn't need the description, descriptionHTML, and parentCerts fields from the database. If we multiply the total size of these three data properties’ values by the number of cards that will appear on the landing page (or in the entire site), we essentially have a considerable number of kilobytes (or more) that can be trimmed off the request response(s) – equaling some significant performance optimization.
Since I’d be using MongoDB for a database it made sense to look for a NodeJS framework that could be used to implement a GraphQL API – one that also leverages Mongoose (ORM). So, after conducting further research I settled on developing the learning course API with NestJS.
The "E" in MERN would be provided through Apollo Server Integration for Express V5 (@as-integrations/express5)
NestJS Framework
Nest JS allows developers to define schema by using models (classes) that are augmented with annotations or decorators. Apart from the schema we also need the input types, DTOs (Data Transfer Objects), services, repositories, resolvers, and controllers. These constitute a set of assets that make it possible to make requests with standard routes, or alternately with GraphQL queries.
Ensuring Proper Data Structure(s) with Mongoose
The data for this project comprises specific structures that are modeled with Mongoose Schemas that allow for specifying TYPE validation parameters. Note how the Schema, Data Transfer Object, and InputType are base classes (in the following code example), that were created to minimize any possible repetition in later uses. Such could be an undoubtedly similar CreateCourseDto, which would require various changes to its strictness on a few properties.
In the first code example below we have CourseBase Schema, which defines the Courses Collection. The following code example presents the CourseBaseDTO (Data Transfer Object) class and the CourseBaseInput class for validation below it:
Entity Relationship Diagrams
During the data modeling process it was necessary to continually examine and refine a set of ER diagrams.
Optimizing the Response with GraphQL
As mentioned before, optimizing the response is crucial for cost-control and adherence to service quotas. Notice how the descriptions, and active properties were excluded from the GraphQL query. Now, have a look at the following code example which shows what the response for this query looks like, after being made in Postman.
Swagger API Output and GraphQL Query Tests
1.) Another great thing about NestJS is that it can be setup to output Swagger documentation. You can view my current setup using this video link: Learning Course API Swagger Documentation
2.) This is a video capture of a GraphQL mutation test, I did in Postman for creating a course in the MongoDB courses collection: GraphQL Mutation Test.
3.) This is another video of a mutation test but with more detail. It focuses on field selection, along with related entity selection capabilities: Detailed GraphQL Mutation Test.
Next.js Folder Structure
Since the data requirements were essentially met for the part of the app I was focusing on, I decided to spend some more time in Next.js. The first task was to build out the folder structure, which directly correlated with the routing. I developed the StoreProvider and slices that would be required for working with Redux and controlling the various states in the application.
What's Next?
In the upcoming Part 2 for this article, I'll be showing more of the frontend architecture setup in the Next.js portion of this project. In React/NextJS I'll specifically be setting up Redux and Thunk, along with consuming the data from the API via Apollo Client to infuse various components with data. Afterwards, there will be some additional work with Docker Compose along with the eventual test deployments to AWS Elastic Container Registry and AWS Elastic Container Service. Have a peek at the docker-compose.yml I've composed in the following code snippet, which I'll be working with in the subsequent phases. These will involve the security (authorization, authentication, guards, and token validation) for the GraphQL API - possibly in Part 3 for this series.
Kind regards,
Emmanuel C. Flint
Frontend Engineer
November 25, 2025
References
Meta Platforms, Inc. (2025). Built-in React Hooks. Next.js. https://react.dev/reference/react/hooks.
Meta Platforms, Inc. (2025). useState. Next.js. https://react.dev/reference/react/useState.
Mysliwiec, K. (n.d.). Mongo. NestJS. https://docs.nestjs.com/techniques/mongodb.
Okeh, O. (2022, June 20). Implementing pagination with GraphQL in NestJS. LogRocket. https://blog.logrocket.com/implementing-pagination-graphql-nestjs.
The GraphQL Foundation. (2025, November 16). Mutations: Learn how to modify data with a GraphQL server. GraphQL. https://graphql.org/learn/mutations.
Vercel, Inc. (2025). Project structure and organization. Next.js. https://nextjs.org/docs/app/getting-started/project-structure.