Skip to main content
  1. All Posts/

penny

eCommerce TypeScript

Penny


An e-commerce starter kit by TakeShape.

Check out the store now at https://penny-demo.takeshape.io/.

You can clone this repo with git to run the Next.js frontend locally (git clone https://github.com/takeshape/penny).
To connect it to a GraphQL backend that TakeShape provides, just deploy the pattern in the .takeshape/pattern
directory. The instructions section of this README will teach you how to do that.

Lighthouse Report: mobile

Category
Score

Path: /
Report

🟢 Performance
98

🟢 Accessibility
100

🟢 Best practices
100

🟢 SEO
100

🟢 PWA
100

Path: /products/basic-tee-6-pack
Report

🟢 Performance
95

🟢 Accessibility
100

🟢 Best practices
100

🟢 SEO
100

🟢 PWA
100

Path: /collections/men
Report

🟢 Performance
96

🟢 Accessibility
100

🟢 Best practices
100

🟢 SEO
100

🟢 PWA
100

The TakeShape project pattern

This starter project composes the following services into a unified GraphQL API:

  • Shopify Admin and Storefront for customer data, product info and payment processing
  • OpenID for identity management
  • ReCAPTCHA for security
  • Gorgias for customer support
  • Klaviyo for newsletter subscriptions
  • REVIEWS.io for product reviews
  • Voucherify for customer loyalty rewards
  • Ship Engine for shipping management

TakeShape is also providing performance and data services for the storefront:

  • TakeShape’s API Indexing speeds up product queries by
    10x and enables lighting fast product search on the frontend
  • TakeShape’s ShapeDB hosts some of the custom content used in this
    build.
graph TD
    A[Frontend Next.js Client] --> |Unified GraphQL API| Mesh{TakeShape's API Mesh}
    Mesh --> |User Authentication| OpenID[OpenID connect]
    Mesh --> |DDoS prevention| reCAPTCHA
    Mesh --> P{Products}
    P --> Shopify[Shopify Admin and Storefront]
    P --> Recharge[Recharge]
    Mesh --> UP{User Profile}
    UP --> |Orders, and Customer Data| Shopify
    UP --> |Subscripitons, and Customer Data| Recharge
    UP --> |Newsletter| Klaviyo
    P --> |Product Reviews| REVIEWS.io
    UP --> |Reviews Written| REVIEWS.io
    UP --> |Shipping info| ShipEngine
    UP --> |Loyalty Points| Voucherify
    UP --> |Customer Support| Gorgias

The frontend stack

The frontend codebase was built with many features that are important for modern composable e-commerce storefronts,
including:

Frameworks, language and styling

Here are the frameworks, language and styling options we went with for this build:

  • Next.js to build the pages and bundle the frontend application
  • NextAuth for user authentication against TakeShape and Shopify
  • TypeScript for type safety and documentation
  • Apollo Client for efficient GraphQL queries against TakeShape
  • Jotai for optimized component state management
  • Storybook for rapid UI prototyping and review
  • Tailwind CSS for beautiful styles.

Continuous Integration

Numerous CI tools have been configured with GitHub Actions. You’ll have a starting point that is easy to test, and easy
to keep error-free and performant.

Unit Tests

  • Jest for React component testing.
  • ESLint for code style and quality.
  • TypeScript ensures a type-safe codebase.
  • GraphQL Codegen extend type-safety to all your GraphQL queries.

E2E Tests

  • Cypress for frontend end-to-end testing and API service mocking

Performance Tests

  • Lighthouse for SEO and browser performance metrics

Set up your lighthouse testing paths in .lighthouse/testPaths.json. By default your homepage will be tested.
IMPORTANT
If you have branch protections in place on your main branch you will need to include a repo secret
PROTECTED_PUSH_TOKEN that is a personal access token with the repo scopes and which is an admin on the project repo.
If you are not using branch protection rules you can replace ${{ secrets.PROTECTED_PUSH_TOKEN }} with
${{ secrets.GITHUB_TOKEN }} in the lighthouse.yml workflow file.

Snapshots

  • Chromatic hosts Storybook stories and provides visual snapshot comparisons

Runtime error reporting

TakeShape specific-tools

We also used a few tools from TakeShape’s ecosystem to simplify our workflow and improve the development process:

  • Next-Auth-All-Access — A NextAuth wrapper that
    provides JWKS-verifiable access tokens for third-party APIs.
  • @takeshape/graphql-validate — GraphQL query validation
    against your TakeShape API.

In the next section, you’ll find a screenshot of the finished store’s homepage.

Screenshot

Getting Started

To get started with TakeShape you need to perform these steps:

  1. Create a new Github repository for your Project and configure .env
  2. Deploy Penny to a new TakeShape Project
  3. Configure Shopify Admin and Shopify Storefront services
  4. Run npm run dev to try out Penny with only Shopify enabled
  5. Configure additional services and customize your Penny project!

Create a new Github repository for your Project

  1. Create a new repository using this repository as a template:
  1. Clone your new repository
  2. Navigate to the project directory in your local terminal and run the npm install command to install all
    dependencies.
  3. Set up your environment variables.
  • Every project will contain a mix of variables defined in .env files and runtime variables defined in a hosting
    provider.
  • Create your project’s .env starter files. Run npm run prepare-env. This repo already contains some .env files
    used for the demo, so you will be prompted to overwrite those files.
  • Because many variables are required to get a fully functional project you should ensure all your services are
    configured before customizing the .env files. Take a look at the .env files now to get a sense of what you’ll need
    before you run the project, and take note of where the various keys and secrets live along the way.
  • .env contains common variables for all runtimes. You can define publicly available variables here. In most cases
    these are prefixed with NEXT_PUBLIC. This file is checked into your repo.
  • .env.local contains variables to use during local development. This file is not checked into your repo and can
    contain all the secrets you need to get your local development environment running, as well as overrides for common
    .env variables.
  • .env.test contains variables and overrides only used when running tests, like jest or cypress.

Warning! Never check secrets into your repo!

  1. Add secrets needed for Github Actions. You can do this by going to your Github project settings then Secrets /
    Actions. You’ll need the following secrets:
  • CHROMATIC_PROJECT_TOKEN if using Chromatic.
  • TS_API_KEY Use the webhook key from earlier.
  • TS_AUTH_TOKEN Can be created in your TakeShape project from the user menu under Access Tokens.
  • TS_PROJECT_ID Can be copied from your TakeShape project dashboard.

Deploy Penny to a new TakeShape Project

  1. Create a TakeShape project using the pattern in this repo. This button will deploy the project for you:
  1. Generate an anonymous and a webhook TakeShape API key. You need these two API keys, and they must have different
    permissions scopes. Here’s how to create them:
  • Navigate to the Settings tab in your TakeShape project’s dashboard.
  • Select the API Keys option in the left sidebar.
  • Select the New API Key button at the top-right of the page.
  • Name the first API Key anything you want; just be sure to grant it anonymous permissions.
  • Save the key in your .env file as NEXT_PUBLIC_TAKESHAPE_ANONYMOUS_API_KEY.
  1. Get your TakeShape project’s API Endpoint. Here’s how:
  • Navigate to the Home tab of your TakeShape project’s dashboard in the web client. Scroll down to the Useful
    Snippets
    section, and copy the API Endpoint there.
  • Save the endpoint in your .env file as NEXT_PUBLIC_TAKESHAPE_API_URL.
  1. Commit changes to .env

NextAuth and OpenID

This project uses NextAuth in combination with the @takeshape/next-auth-all-access package for user authentication. It
also uses OpenID for identity management. The following instructions will walk you through setting up OpenID as a
service provider in your TakeShape project, and configuring NextAuth with @takeshape/next-auth-all-access.

Setting up OpenID

  1. In the Home tab of your TakeShape project, select OpenID from the list of services. You will be taken to the
    OpenID service configuration page.

  2. Add your store’s URL to the Issuer URL field, and enter the same URL with
    /api/auth/all-access/.well-known/openid-configuration appended to the end of it in the OpenID Configuration
    URL
    .

    Note: Your store URL should be the public-facing URL of your website, not necessarily your myshopify.com URL.

  3. Copy the generated url in the Audience field and save it somewhere secure. You’ll need it for your one of your
    project’s environment variables.
  4. Select the Save button at the top-right of the OpenID service page.
  5. Update your .env file in your Next.js project’s directory with the following variables:
  • Add a NEXT_PUBLIC_TAKESHAPE_AUTH_AUDIENCE variable with the generated Audience URL from your OpenID provider.
  • Add a NEXT_PUBLIC_TAKESHAPE_AUTH_ISSUER variable with the same URL you provided for the Issuer URL field on your
    OpenID provider. This should be your store’s URL.

Setting up NextAuth

Use our @takeshape/next-auth-all-access package to create and sign an access token for your logged-in users.
To generate your keypair, use the following command from the root of your project repo and follow the printed
instructions.

npx @takeshape/next-auth-all-access generate-keys

You will then need to follow these steps:

  1. Add the variable ALLACCESS_PRIVATE_KEY with your private key to your .env.local file and to your hosting
    provider’s environment.
  2. Commit the ./keys/jwks.json file to your repo, push, and build. Your key will need to be web accessible at the URL
    you configured in TakeShape before authentication will work.

Shopify Admin and Shopify Storefront

Warning! Connecting this project to a live Shopify store WILL enable real purchases. If you just want to play
around without risking real charges,
set your store’s payments to Test Mode
and use appropriately scoped Shopify API keys. When testing purchases,
always use
Shopify’s accepted fake credit card information.

This project uses Shopify for e-commerce functionality. These instructions assume you’ve already
created a Shopify store. You don’t need to have Shopify Plus to use any of the features
described here.
Follow these instructions to connect your Shopify store’s Admin and Storefront APIs to both your TakeShape project and
the frontend Next.js project.

  1. Create a Shopify store if you don’t already have one.
  2. Navigate to your store’s admin site by visiting https://your-store.myshopify.com/admin, substituting “your-store”
    with the name of your store.
  3. Configure your Shopify checkout experience.

This project uses Shopify’s checkout experience. That means when a customer is ready to purchase, they are redirected to
a checkout flow that Shopify generates. The only downside is, shopify’s checkout flow will send users to your shopify
store, not your headless store, when they’re done. To force Shopify’s checkout experience to redirect to your headless
storefront, you must use their Liquid templating language. These instructions show
you how:

  • In your store’s admin UI, select the âš™ Settings button. A settings menu will appear. Select Checkout on the
    left.

  • Scroll down to the Order status page settings. In the Additional Scripts text area, add the following script.
    There are two URLs the order can possibly be redirected to. Be sure to add your store’s root URL to the second one,
    under the {% else %}:

      {% if checkout.attributes.redirect_origin %}
      <script> window.location = "{{ checkout.attributes.redirect_origin }}/?shopify_checkout_action=success"; </script>
      {% else %}
      <script>...