npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@akasha-platform/vendure-craftjs

v0.0.3

Published

A set of hooks and components to provide components that interact with vendure and can be integrated into craftjs.

Downloads

6

Readme

vendure.craft.js

Overview

@akasha-platform/vendure-craftjs is part of a set of open source repositories which together can be setup to serve a flexible content and ecommerce framework based on microservices/-frontends architecture.

The use of vendure.io as an e-commerce and GraphQL backend and craft.js with a set of customized components has the potential to serve as a solid but flexible interface between merchants/content creators and their customers/target audience.

What is vendure.io?

vendure.io is "A modern, headless GraphQL-based e-commerce framework built with TypeScript & Nodejs"

Its small footprint, easy customisation, extendability and microservice oriented architecture make vendure a perfect candidate for a modern content/e-commerce platform.

What is craft.js?

craft.js is " a React framework for building powerful & feature-rich drag-n-drop page editors."

With craft.js it is possible to fairly quickly build up customised drag and drop page builders as it servers only as a page building framework and lifts off the burden of handling editor state, history and drag and drop handling from you shoulders.

It is possible to build simple React Components with an additional few lines of code to make them compatible with craft.js, however we will see later that the @akasha-platform/craftjs-tool library takes care of a lot of the setup for us.

How do the two work together?

Since both, craft.js and vendure.io do not work together out of the box, a set of repositories was created to make this marriage possible. The microservices are the following:

  • Shop API (Customer facing GraphQL API)
  • Admin API (Admin facing GraphQL API)
  • Admin UI (Admin facing UI)
  • Shopfrontend (Customer facing UI)
  • Page Editor (Admin facing publishing UI)

In order to make this work both, craft.js and vendure.io need to be extended to support the funtionalities required by @akasha-platform/vendure-craftjs.

On the backend side the @akasha-platform/vendure-document-plugin is used to provide an admin facing GraphQL API for managing page trees, meta-data and publishing criteria.

On the frontend side we need to tell craft.js how to fetch page contents and render components using @akasha-platform/craftjs-tools and @akasha-platform/vendure-craftjs.

Setup

This documentation will show you how to setup vendure.io, install all requirements, setup a craft.js page builder and how to extend both the customer facing UI and the admin facing UI (some parts of the vendure admin UI will not be covered).

Project setup

The final project will have the following folder strucure.

example-project/
|-- vendure/
|  |-- package.json
|  |-- ...
|
|-- page-builder/
|  |-- package.json
|  |-- ...
|
|-- shop-front/
|  |-- package.json
|  |-- ...

Installation (Admin facing)

Vendure

Install Vendure
yarn create @vendure vendure

When it asks for the database you're using, select SQLLite for simplicity. If you want to use other database engines you will have to make sure that they are up and reachable for the installation process.

Select Typescript as your programming language and select the rest as you desire.

Configure Vendure
yarn add @akasha-platform/vendure-document-plugin
// vendure-config.ts

import { DocumentPlugin } from "@akasha-platform/vendure-document-plugin";

export const config = {
  /*...*/

  plugins: [/*...*/ DocumentPlugin],
};

and then simply run

yarn migration:generate document-plugin
yarn migration:run document-plugin

This should be enough to have the backend setup. Now start the development environment and check if everything went ok by running

yarn start

If everything went fine, you should be able to login into the shop backend via http://localhost:3000/admin/login

Page Builder

Back in our main project folder we are ready to create our page builder application. You might need to install install-peerdeps for convenience.

Install Page Builder
yarn create react-app page-builder --template typescript
cd ./page-builder
install-peerdeps @akasha-platform/vendure-craftjs

After using install-peerdeps you might want to rearrange some of the packages in the dependencies section of your package.json files to devDependencies and don't forget to re-run yarn install.

Configure Page Builder

In order to actually use the Page Builder we will have to implement a redux store and an apollo client for use by the components delivered with @akasha-platform/vendure-craftjs.

First we will create our redux store:

// ./src/store.ts
import { combineReducers, configureStore } from "@reduxjs/toolkit";
import { exportedUserComponentsReducer } from "@akasha-platform/craftjs-tools";
import { navigationReducer } from "@akasha-platform/vendure-craftjs";

const reducer = combineReducers({
  exportedComponents: exportedUserComponentsReducer,
  navigation: navigationReducer,
});

const store = configureStore({
  reducer,
});

export type RootState = ReturnType<typeof store.getState>;

export default store;

And now our clients:

// ./src/client.ts
import {
  ApolloClient,
  ApolloLink,
  createHttpLink,
  from,
  InMemoryCache,
} from "@apollo/client";
import { onError } from "@apollo/client/link/error";

const AUTH_TOKEN = "vendure-auth-token";

const middlewareAuthLink = new ApolloLink((operation, forward) => {
  const token = localStorage.getItem(AUTH_TOKEN);
  const authorizationHeader = token ? `Bearer ${token}` : null;
  operation.setContext({
    headers: {
      authorization: authorizationHeader,
    },
  });
  return forward(operation);
});

const afterwareLink = new ApolloLink((operation, forward) => {
  return forward(operation).map((response) => {
    const context = operation.getContext();
    const {
      response: { headers },
    } = context;

    if (headers) {
      const refreshToken = headers.get("vendure-auth-token");
      if (refreshToken) {
        localStorage.setItem(AUTH_TOKEN, refreshToken);
      }
    }

    return response;
  });
});

const errorLink = onError(({ graphQLErrors, networkError }) => {
  if (graphQLErrors)
    graphQLErrors.map(({ message, locations, path }) =>
      console.log(
        `[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`
      )
    );

  if (networkError) console.log(`[Network error]: ${networkError}`);
});

export const adminClient = new ApolloClient({
  link: from([
    errorLink,
    middlewareAuthLink,
    afterwareLink,
    createHttpLink({
      uri: "http://localhost:3000/admin-api",
    }),
  ]),
  cache: new InMemoryCache(),
});

export const frontendClient = new ApolloClient({
  link: from([
    errorLink,
    middlewareAuthLink,
    afterwareLink,
    createHttpLink({
      uri: "http://localhost:3000/shop-api",
    }),
  ]),
  cache: new InMemoryCache(),
});

Last but not least we setup our App.tsx to show the craft.js editor. To use a react-redux provider we will have to install it first:

// ./src/App.tsx
import { muiTheme, Resolver } from "@akasha-platform/craftjs-tools";
import {
  AppEditor,
  LoginBox,
  vendureUserComponents,
} from "@akasha-platform/vendure-craftjs";
import { ApolloProvider } from "@apollo/client";
import { Frame } from "@craftjs/core";
import { MuiThemeProvider } from "@material-ui/core";
import React, { useEffect, useState } from "react";
import { Provider } from "react-redux";
import { adminClient, AUTH_TOKEN, frontendClient } from "./client";
import store from "./store";

export const App = () => {
  const resolver = new Resolver({
    ...vendureUserComponents,
  });
  resolver.resolve();

  const [token, setToken] = useState(localStorage.getItem(AUTH_TOKEN));

  useEffect(() => {
    function updateToken() {
      setToken(localStorage.getItem(AUTH_TOKEN));
    }
    window.addEventListener("storage", updateToken);

    return () => {
      window.removeEventListener("storage", updateToken);
    };
  }, [setToken]);

  return (
    <>
      {token ? (
        <AppEditor
          store={store}
          adminClient={adminClient}
          frontendClient={frontendClient}
          resolver={resolver}
          editMode={true}
        >
          <Frame>{resolver.create("ContentArea")}</Frame>
        </AppEditor>
      ) : (
        <Provider store={store}>
          <ApolloProvider client={adminClient}>
            <MuiThemeProvider theme={muiTheme}>
              <LoginBox />
            </MuiThemeProvider>
          </ApolloProvider>
        </Provider>
      )}
    </>
  );
};

export default App;

After running

yarn start

We should be able to start the editor now and directly start to use it.

Installation (Customer facing)

Usage

Features

Content Components

Content Area
Content Editable
Vendure Image

Data driven Components

Product
Collection
Collections
Cart Area
Checkout Area

Form Components

Checkout Form
GraphQL Forms

Pages & Routing

Document Tree and Publishing (+ SEO)
Fetching data based on route properties

Development

Creating Components for use in Editor

"It is just simple React"

Creating Components for GraphQL Data

Products
Collections
Orders/Carts...
Checkout
Search
Custom Components

Wrapping with @akasha-platform/craftjs-tools

Creating settings forms with @akasha-platform/craftjs-tools

Creating actions for use in @akasha-plaform/craftjs-tools's ViewPort

Extending the Editor

Adding Components

Adding Actions

Extending the GraphQL Schema