Source Code Plugins

  • Browser: A Chromium based web browser like Google Chrome
  • Browser extensions: Vue.js Devtools , Cross Domain CORS to disable CORS security checks and GraphiQL to test GraphQL queries.
  • IDE:
    • IntelliJ with Vue.js and Tailwind Plugin - or
    • Visual Studio Code with Volar and Tailwind extension

Set up the project

1. Get the source code

git clone git@...

2. Install nvm & switch to required node version

cd ./path-to-repository && nvm install && nvm use

3. Install dependencies

npm install

4. Create & adjust iframe.html

cp iframe.html.dist iframe.html

Now open iframe.html and

  • replace [[[ URL TO YOUR WEBSHOP ]]] with the URL to your web shop you want to use for development.
  • replace [[[ ARTICLE NUMBER ]]] with the number of the article you like to use for development.
  • replace [[[ LOCALE ]]] with the locale code like en-GB or de-DE you like to use for development.

5. Run development server

This command will start the development server and open the designer in your browser.
npm run dev

Make sure everything is working as expected. If not, check for errors and XHR responses in your browser’s web developer tools. If you get CORS issues you could install a browser extension that disable these checks. For your production environment you should make sure domain names match or set appropriate CORS headers.

Create a plugin

Although you are able to fork this repository and change the code of the designer wherever you like it may not be the best option as you would lose compatibility to future updates of the designer.

Instead you could create a plugin which adjusts the components and business logic of the designer without the need to touch even a single file shipped with the designer.

1. Create plugin entry point

Create a new directory inside ./src/plugins and place a new file index.ts in there

mkdir ./src/plugins/my-plugin && touch ./src/plugins/my-plugin/index.ts

2. Add a default-exported initialization function inside that file

import { DependencyContainer } from 'tsyringe';

export default function initialize(container: DependencyContainer): Promise<void> {
  return new Promise<void>((resolve) => {
    resolve();
  });
}

The designer will automatically load the file and calls that function with the DI container.
You can replace Vue.js components and business facades within the container.

3. Replace a component

  • Create your own component inside your plugin directory, for instance ./src/plugins/my-plugin/MyQrCodeComponent.vue

  • Implement your component, for instance

<template>
    <button @click="onClick()">My QR Code button</button>
</template> 

<script lang="ts" setup>
function onClick() {
    console.log('My QR Code implementation');
}
</script>
  • Use the DI container to register your component.
import { DependencyContainer } from 'tsyringe';
import MyQrCodeButtonComponent from './MyQrCodeButtonComponent.vue';

export default function initialize(container: DependencyContainer): Promise<void> {
  return new Promise<void>((resolve) => {
    container.register('action/QrCodeButtonComponent', {
      useValue: MyQrCodeButtonComponent,
    });

    resolve();
  });
}

4. Reuse & replace business logic

Vue.js components are light weight and usually only contain a few lines of Typescript code. Most business logic can be found in /src/business. While you can replace that code as well it’s recommended to not do so. Instead, create your own logic - which may use the business logic of the designer internally - and replace the facade method.

For instance, to add your own logic to the image upload functionality, create your own image facade:

./src/plugins/my-plugin/image-facade.ts

Content:

import { inject, singleton } from 'tsyringe';
import { ResultAsync } from 'neverthrow';
import ImageFacade, { IImageFacade } from '../../business/image';

@singleton()
class MyImageFacade implements IImageFacade {
  constructor(
    @inject(ImageFacade) private imageFacade: IImageFacade,
  ) {}

  uploadImage(imageFile: File): ResultAsync<string, Error> {
    // add your own logic, call original logic

    return this.imageFacade.uploadImage(imageFile);
  }
}

export default MyImageFacade;

Use the DI container to register your facade:

import { DependencyContainer } from 'tsyringe';
import MyImageFacade from './image-facade';
import ImageFacade, { IImageFacade } from '../../business/image';

export default function initialize(container: DependencyContainer): Promise<void> {
  return new Promise<void>((resolve) => {
    const originalImageFacade = container.resolve(ImageFacade);
    const myImageFacade = new MyImageFacade(originalImageFacade);

    container.registerInstance<IImageFacade>(ImageFacade, myImageFacade);

    resolve();
  });
}

Build

You can build the designer using npm run build

This will create the minified, compiled output files inside /dist. You can copy these files to your shop server. Make sure the shop plugin is configured to use your custom build instead of the default build shipped with the plugin.

Used libraries & frameworks

This product designer would not have been possible thanks to a lot of Open Source libraries and frameworks. The most import frameworks you should know about are


© Christian Kilb
Saseler Mühlenweg 2
22395 Hamburg

Phone (no support, only legal issues): 0173 / 9763987
E-Mail: contact@cilb.de