Giter VIP home page Giter VIP logo

vendure-nextjs-storefront's Introduction

Vendure NextJS Storefront

This is a NextJS starter for Vendure in the shape of a demo e-commerce shop. It's still in alpha, but feel free to read the concepts, run the store locally or just check out how it works at shop.aexol.com.

Installation

  1. Clone this repo via SSH, HTTPS or the GitHub CLI.
  2. Install packages using npm i
  3. Setup your vendure server locally and run it on http://localhost:3000/
  4. Create a .env file in the root of the project and add the following variables:
NEXT_PUBLIC_HOST="http://localhost:3000/shop-api"
  1. Then feel free to run it locally using npm run dev

Important

Reminder: you need to also have the Vendure store running locally to use this storefront

Tip

You can read about how to set that up in the Vendure Server section below

Table of contents

Vendure Server

This storefront requires a Vendure V2 server. You can either run a local instance, or use our public demo server.

Our demo of Vendure server (MinIO & Postgres & SMTP) can be found here to see all changes.

For the best experience when using our demo, you'll need to apply some ‘small’ modifications.

Here's a list of those small changes to the Vendure server:

  • apply two collections all and search. Both of them should contain all products (or not? for cases with gift cards / shipping-protections)
  • add the stock level as a number value and not as enum values
export class ExactStockDisplayStrategy implements StockDisplayStrategy {
  getStockLevel(
    ctx: RequestContext,
    productVariant: ProductVariant,
    saleableStockLevel: number
  ): string {
    return saleableStockLevel.toString();
  }
}

export const catalogOptions: VendureConfig["catalogOptions"] = {
  stockDisplayStrategy: new ExactStockDisplayStrategy(),
};

Zeus

We use GraphQL Zeus to provide Selectors for certain GraphQL query parts. You can think of Selectors as fragments in GraphQL, just with the added type-safety.

Page naming convention

In this starter, we're following a fairly simple naming convention for pages, that aligns with DDD (Domain-driven design) principles. Each page file is named using the format page-name.page.tsx, where page-name represents the name of the page or route. For example, the main page of your application would be named index.page.tsx. We're also using slug pages for products and collections, where we have a products and collections folder with a [slug].page.tsx where the [slug] is replaced by product or collection name fetched from the backend as props. This allows us to dynamically generate those pages at scale, while maintaining a simple to navigate structure with routes like /collections/electronics/ or /products/laptop/. Using this naming convention helps maintain a clean and organized folder structure that reflects the structure of your application's domains or features. By separating pages into their respective folders and adopting a consistent naming convention, you can easily locate and manage your application's routes and easily navigate any issues that might arise.

Internationalization with i18next

As most e-commerce shops use localization to reach clients who use different languages we have also added integrated i18next to handle translations. This makes it really easy to add and update translated content. Here's how we use i18next:

  1. Translation Files: We maintain separate JSON translation files for each supported language. These files contain translation keys and their corresponding localized text. For example, you might find the English translation file for home page at public/locales/en/homePage.json

  2. Locale Configuration: We configure i18next to load the appropriate translation files based on the user's selected locale.

  3. Integration with React: We use the next-i18next package to integrate i18next with React components, making it seamless to access translations in your React components via a simple useTranslation hook which will then always use the matching translation for the user's selected locale.

import { useTranslation } from 'next-i18next';

export const Home: React.FC = () => {
    const { t } = useTranslation('homepage');

    return (
        <Layout>
                <Hero
                    cta={t('hero-cta')}
                    h1={t('hero-h1')}
                    h2={t('hero-h2')}
                    desc={t('hero-p')}
                    link="/collections/all"
                />
        </Layout>
    );
};

Tip

For quick localization you can use DevTranslate to translate json files into up to 28 languages at the same time.

Icons

Lucide icons is an open source library which contains over one thousand svg icons and symbols separated into official packages, to make it easier to pick one for your project. Head on over to lucide.dev and check them out yourself.

Styles

We really like using Tailwind - that's why we are building our own engine based on styled components with props that work similarly to Tailwind. For example here's our Stack component:

export const Stack = styled.div<BaseFlexParams>`
    gap: ${p => p.gap || 0};
    display: flex;
    flex-direction: ${p => (p.column ? (p.reverse ? 'column-reverse' : 'column') : p.reverse ? 'row-reverse' : 'row')};
    flex-wrap: ${p => (p.flexWrap ? 'wrap' : 'nowrap')};
    justify-content: ${p =>
        p.justifyBetween ? 'space-between' : p.justifyCenter ? 'center' : p.justifyEnd ? 'end' : 'start'};
    align-items: ${p => (p.itemsCenter ? 'center' : 'initial')};
`;

With the props set up like that you can then use it almost like you would with Tailwind (just without ClassName):

<Stack column gap="2rem">
  {children}
</Stack>

Theme

Theming is provided by Emotion and some generic functions.

You can use values from the theme with thv which returns a function that consumes the theme and returns just the value or the usual method with ${p => p.theme}. You can see both uses in the example below:

import { thv } from '@/src/theme';
import styled from '@emotion/styled';

export const IconButton = styled.button<{ isActive?: boolean }>`
    color: ${thv.button.icon.front};
    border: 0;
    border-radius: 100%;
    font-weight: 600;
    outline: 0;
    width: 2.4rem;
    height: 2.4rem;
    display: flex;
    align-items: center;
    justify-content: center;
    background: ${p => p.theme.button.icon.back || 'transparent'};
    svg {
        width: 2rem;
        height: 2rem;
    }
    :hover {
        box-shadow: none;
    }
`;

Useful Links

Who are the authors?

We are devs and contributors to the GraphQL ecosystem with a lot of experience and we want to enter Vendure to create developer-friendly e-commerce solutions that don't rely on clunky and outdated stuff like Shopify's Liquid wrapped with JavaScript.

Roadmap

  • Finish this starter
  • Deployment of the storefront connected to demo shop
  • Basic Cart functionality
  • Basic Checkout process
  • Design implementation
  • Basic Payment process
  • Basic User Profile
  • Search products
  • Filters
  • Localization with devtranslate.app
  • Adding Static Git CMS MDTX
  • Configure SEO and schema.org for every site
  • Assure ISR ready on every sub site
  • Migrate to the new next router

vendure-nextjs-storefront's People

Contributors

aexol avatar aleksander-aexol avatar aleksanderbondar avatar borowskir avatar ghosttly avatar magda9005 avatar michal-aexol avatar rafallborowski avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

vendure-nextjs-storefront's Issues

Suggestion: Add .env.example and Guide Note for Easier Setup

Hello,

First off, congratulations on the exceptional work on the Vendure Next.js storefront. I have a small suggestion that could potentially improve the onboarding experience for new users. It would be useful to include an .env.example file in the root of the project, with something like NEXT_PUBLIC_HOST=https://vendure-dev.aexol.com/shop-api/, and to emphasize the need to create its own .env file based on this model in the installation guide. This minor addition could streamline the initial setup process.

Thank you for considering this suggestion

New product issue

Hello. I'm complete beginner on vendure commerce. I'm just trying out.
When I add new product from vendure admin, it's visible on the listings. But it raises an 404 error when I try to visit the product detail page.
How can I fix the issue

Can't change item count in shopping cart

hello
I'm running your code and at the shopping cart drawer, when I want change the quantities the item from the cart, I get the error below, While this problem does not exist on https://shop.aexol.com.
please help me
thanks.

Error
    at eval (client.ts:59:27)
    at async setItemQuantityInCart (cart.ts:102:41)
{
    "errors": [
        {
            "message": "This order does not contain an OrderLine with the id 893",
            "locations": [
                {
                    "line": 1,
                    "column": 12
                }
            ],
            "path": [
                "adjustOrderLine"
            ],
            "extensions": {
                "code": "USER_INPUT_ERROR"
            }
        }
    ],
    "data": null
}

Is there any plan to use NextUI with App router?

Congratulations and thank you for the amazing functional storefront. Not an issue but suggestions based on the few changes we tried to made in this storefront. Using NextUI/Shadcn (as it includes tailwind) or any other libraries which supports or uses tailwind could be more efficient for rapid development and optimizing production bundle. Not only that but theming using preset, config or plugins will be more easy then ever. Just curious if you have this in your future plans!

Sometimes back button is not working

First, thanks for the starter template. Its really helpful.

Steps to reproduce the issue.

  1. Navigate to home and garden in new tab. https://shop.aexol.com/collections/home-garden/
  2. Click on filters and apply color: wood filter.
  3. Click on the first product.
  4. Navigate back using browser back button.

The URL is updated but the content is not.
Content is updated once you refresh the page.

Browsers
Chrome 110.0.5481.77 (Official Build) (64-bit)
Firefox 122.0.1 (64-bit)

If you don't have time bandwidth to fix the issue, would you be able to provide any clues about what might be causing it? Your assistance would help a lot.

Thanks.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.