Migration of a Single Product from WooCommerce to Webflow
In this article are provided steps that need to be executed to properly fetch product information from the WooCommerce store and upload it to the Webflow store. We will pick a single product by its slug and create the same one on the Webflow store where we map the product's name, slug, description, main image, and price. Extending this functionality to migrate multiple products is relatively simple, and is briefly mentioned at the end.
GitHub Repository
Complete implementation of the solution shown in this article can be cloned from GitHub repository: https://github.com/emir-gradient/woocommerce-to-webflow-migration.
Preparing stores for local development
For the WooCommerce store, one should first install WordPress and then WooCommerce plugin.
- Installing WordPress is described in How to install WordPress.
- Installing WooCommerce is described in Installing and Uninstalling WooCommerce.
When it comes to Webflow since it is SaaS and not open source, for local development, we register one account on webflow.com and then follow available Webflow instructions to create an e-commerce website. While one can not publish an e-commerce site on Webflow for free, one can test it out and Webflow API can be utilized.
Once both stores are ready, we need to configure WooCommerce for API usage and get API keys. On the Webflow site, we only need to retrieve API keys.
- For WooCommerce, perform the steps described in the article WooCommerce REST API.
- For Webflow, perform the steps described in Webflow CMS API Reference.
Starting Node.js project and installing dependencies
Having the necessary API keys, we are ready to start developing integration code between WooCommerce and Webflow. We will utilize Node.js to implement the solution that performs product migration from WooCommerce to WebFlow.
Let us initialize an empty Node.js project:
$ yarn init
If you do not have or use yarn, you can utilize npm.
$ npm install -g yarn
Both products (WooCommerce and Webflow) have Node API clients developed and shared on the npm repository. So, we install API clients as dependencies of our project:
$ yarn add @woocommerce/woocommerce-rest-api webflow-api
In package.json, make sure to add the start script and define the project type as a module:
{
"name": "woocommerce-to-webflow-migration",
"version": "1.0.0",
"license": "MIT",
"type": "module",
"scripts": {
"start": "node src/main.js"
},
"dependencies": {
"@woocommerce/woocommerce-rest-api": "^1.0.1",
"webflow-api": "^0.8.1"
}
}
Finally, we create a directory src and create a main.js file with the following content:
async function main() {
console.log('Running');
}
main().then(() => {
console.log('Finished');
});
Run the following command in the root of the project:
$ yarn start
If all went properly, the result should be similar to this:
yarn run v1.22.19
$ node src/main.js
Running
Finished
Fetching products from WooCommerce
To be able to publish products to Webflow, we need to fetch them from WooCommerce store first. For this purpose, WooCommerceRestApi class is designed and utilized.
How to retrieve products from the WooCommerce store is presented in the following code snippet:
const wooCommerceApiClient = new WooCommerceRestApi({
url: 'woo-commerce store url',
consumerKey: 'ck_abcabcabcabcabcabcbacbabcbabbcabcbabc',
consumerSecret: 'cs_alkjlskdfjlskdfjlskdfjlskdfjlskdjflsdk',
version: 'wc/v3'
});
const productsResult = await this.api.get('products');
All products from our WooCommerce store are referenced by productsResult.
To retrieve one product (by its slug) we will utilize the get products API endpoint with a slug filter. Also, to organize our code a bit, we will define one WooCommerceIntegration class. It will be utilized for all API operations related to WooCommerce API usage. The content of WooCommerceIntegration class is:
import pkg from "@woocommerce/woocommerce-rest-api";
const WooCommerceRestApi = pkg.default;
export class WooCommerceIntegration {
constructor(consumerKey, consumerSecret, storeUrl) {
this.consumerKey = consumerKey;
this.consumerSecret = consumerSecret;
this.storeUrl = storeUrl;
this.api = new WooCommerceRestApi({
url: this.storeUrl,
consumerKey: this.consumerKey,
consumerSecret: this.consumerSecret,
version: 'wc/v3'
});
}
async getProduct(slug) {
const products = await this.api.get('products', {
slug
});
return products.data.length ? products.data[0] : null;
}
async getStoreCurrencyCode() {
const currentCurrency = await this.api.get('data/currencies/current');
return currentCurrency.data.code;
}
}
Except for instantiating WooCommerceRestApi and retrieving products by slug, we can also see getStoreCurrencyCode method in the example. We will utilize it to transfer product currency to Webflow store. An assumption is made here that all articles in source WooCommerce store have price defined in the same currency.
Mapping WooCommerce product structure to Webflow
As independent services, WooCommerce and Webflow have different data structures for representing products. To be able to provide products to Webflow API, we need to perform mapping of WooCommerce product structure to Webflow. To do so, we write mapping method as follows:
toCreateWebflowProductDto(wooCommerceProduct, wooCommerceStoreCurrencyCode) {
return {
product: {
fields: {
_draft: true,
_archived: false,
name: wooCommerceProduct.name,
slug: wooCommerceProduct.slug,
description: wooCommerceProduct.description,
}
},
sku: {
fields: {
_archived: false,
_draft: true,
name: wooCommerceProduct.name,
slug: wooCommerceProduct.sku,
'main-image': {
url: wooCommerceProduct.images[0].url
},
price: {
unit: wooCommerceStoreCurrencyCode,
value: wooCommerceProduct.price,
}
},
}
};
}
The resulting data structure is applicable for Webflow API to create products.
Some changes/adaptations are needed though.
When we analyze further, we can recognize the two important notes why this mapper will not work properly:
- The description in WooCommerce is HTML5 since it includes styling of the Product description.
- The price in WooCommerce is retrieved as a string. Also, it includes the decimal point. Webflow API accepts product price as the integer. So, if we want the price to be $42.00 we need to send 4200. Or, as another example, if we want the price to be $243.55, we need to send 24355 as the price value.
Considering these two notes, the final ProductMapper implementation looks like:
export class ProductMapper {
toCreateWebflowProductDto(wooCommerceProduct, wooCommerceStoreCurrencyCode) {
return {
product: {
fields: {
_draft: true,
_archived: false,
name: wooCommerceProduct.name,
slug: wooCommerceProduct.slug,
description: this.parseDescriptionStripTags(wooCommerceProduct.description),
}
},
sku: {
fields: {
_archived: false,
_draft: true,
name: wooCommerceProduct.name,
slug: wooCommerceProduct.sku,
'main-image': {
url: wooCommerceProduct.images[0].url
},
price: {
unit: wooCommerceStoreCurrencyCode,
value: this.parsePriceToInt(wooCommerceProduct.price),
}
},
}
};
}
parseDescriptionStripTags(description) {
return description.replace(/<\/?[^>]+(>|$)/g, "");
}
parsePriceToInt(price) {
if (price.indexOf('.') === -1) {
return parseInt(price) * 100;
} else {
const parts = price.split('.');
if (parts[1].length > 2) {
parts[1] = parts[1].substring(0, 2);
} else if (parts[1].length === 1) {
parts[1] += '0';
}
price = parts.join('');
return parseInt(price);
}
}
}
By finalizing this step, we are able to retrieve the product from WooCommerce and map it to the appropriate structure for WebFlow API.
Creating products in the Webflow store
The next step in our integration is to actually upload product data to Webflow. For this purpose, we utilize WebflowApi class. To upload the product we need to identify our site id first. After that, we execute the following method:
async createProduct(siteId, createWebflowProductDto) {
try {
await this.api.post(`/sites/${siteId}/products`, createWebflowProductDto);
} catch (e) {
console.log(e);
}
}
Complete implementation of the WebflowIntegration class, which utilizes all Webflow API operations is given in the following section:
import Webflow from "webflow-api";
export class WebflowIntegration {
apiKey = null;
api = null;
constructor(apiKey) {
this.apiKey = apiKey;
this.api = new Webflow({ token: this.apiKey });
}
async getFirstSite() {
const sites = await this.api.sites();
return sites.length ? sites[0] : null;
}
async createProduct(siteId, createWebflowProductDto) {
try {
await this.api.post(`/sites/${siteId}/products`, createWebflowProductDto);
} catch (e) {
console.log(e);
}
}
}
In this example, it is assumed that the user of API has only one site on Webflow. With that assumption, it is safe to take the first site (on index 0) since it should be the only one retrieved from the API.
Usage of all created modules
With all modules ready, all necessary steps for product migration from WooCommerce to Webflow are covered. The following is implemented:
- Retrieving product from WooCommerce,
- Mapping products from WooCommerce to Webflow structure,
- Publishing the product to Webflow.
Finally, in the main.js we are utilizing all created modules having the following result:
import { WebflowIntegration } from "./integrations/WebflowIntegration.js";
import { WooCommerceIntegration } from "./integrations/WooCommerceIntegration.js";
import { ApiKeys } from "./constants/api-keys.js";
import { ProductMapper } from "./mapper/product-mapper.js";
async function load() {
const productSlug = 'shoes';
const webflowIntegration = new WebflowIntegration(ApiKeys.Webflow);
const wooCommerceIntegration = new WooCommerceIntegration(
ApiKeys.WooCommerceConsumerKey,
ApiKeys.WooCommerceConsumerSecret,
"http://host:port");
const productMapper = new ProductMapper();
const webflowSite = await webflowIntegration.getFirstSite();
const wooCommerceProduct = await wooCommerceIntegration.getProduct(productSlug);
const wooCommerceStoreCurrencyCode = await wooCommerceIntegration.getStoreCurrencyCode();
const createWebflowProductDto = productMapper.toCreateWebflowProductDto(wooCommerceProduct, wooCommerceStoreCurrencyCode);
await webflowIntegration.createProduct(webflowSite._id, createWebflowProductDto);
}
load().then(() => {
console.log("Finished!");
});
By starting this program with the following command, the product with slug 'shoes' should be properly published to the Webflow store.
$ yarn start
Get an Offer
Contact Us or Schedule a Meeting with us to get an offer for our development & consulting services regarding your current or next WooCommerce or WebFlow project.
Sp collection
Electronic items watches,smart watch, headphones air buds, airports, speaker all electronic items for girls and boys
Vel voluptas quidem
Explicabo Lorem dol