The reality of support for Magento 2 shipping methods in headless storefronts

Shipping methods are essential for each web store owner, and one of the most frequently asked questions about headless storefront is: 'Does PWA Studio (or VSF) support all of the shipping methods available in the Magento backend'. I did a small investigation, and I would like to show you how shipping methods are rendered on the PWA Studio storefront.

Magento 2 as an eCommerce platform offers good support for various shipping methods so typically you are able to find integration for the shipping methods you want. Until you want to build a headless storefront connected with Magento 2, the sentence above for sure, but how support for Magento 2 shipping methods looks when you want to:

  • build a PWA storefront using PWA Studio?

  • build a headless storefront using Vue Storefront?

  • build your own custom headless storefront?

I did a small investigation, and in this article, I would like to show you what is the support for shipping methods, and what options you have when you want to create your own custom shipping method.

Three default Magento 2 shipping methods

Magento 2 offers three simple shipping options:

  • flat rate - straightforward shipping method with fixed prices for each item.

  • table rates - the shipping rates in tables calculate shipping costs using conditions like Weight v. Destination, Price v. Destination, and Number of Items v. Destination. Data used for calculation came from a predefined spreadsheet that is imported to a store

  • free shipping - you can set free shipping based on minimum amount of an order, or set up a cart price rule that is applied when a set of conditions is me

How to configure Magento 2 shipping settings

To configure shipping methods you need to open an admin panel and go to Stores > Configuration > Sales > Delivery methods. You should see the shipping methods configuration:

magento 2 shipping methods

Each shipping method has a similar set of configuration fields. Take a look at the flat rate shipping method:

Magento 2 flat rate shipping method

Shipping methods configuration fields

  • enabled - determinates is shipping method is enabled for a specific scope

  • title - the name of the shipping method that is used on the Magento 2 checkout page

  • method name - the name of the method used next to the title on the checkout page. For example, the default phrase visible on the checkout page for the Flat rate shipping method is “Flat rate - fixed”

  • price - the price of the shipping method that you charge a customer

  • calculate handling fee - the way the handling fee is calculated if included. Options: Fixed / Percent

  • handling fee - the amount to be charged for a handling fee, based on the method you have chosen to calculate the amount (fixed or percent)

  • displayed error message - a message appears in the case when the method is not available

  • ship to applicable countries - thanks to this option you can specify for which countries shipping method is available

  • ship to specific countries - similar to the previous one, but here you can explicitly set countries

  • show method if not applicable - if this option is set to yes, a shipping method will be visible on checkout even is not applicable for some reason.

  • sort order - a number determines the position of this method in the delivery methods list visible on the checkout page

Configure shipping methods in Magento

Please follow these tutorials to configure default shipping methods in Magento:

Flat rate shipping method

Free shipping method

Table rate shipping method

When you complete and go to the Magento checkout page you should see something like this:

shipping costs in Magento 2 checkout for free shipping method, table rate and flat rate (defaults)


Magento 2 shipping methods in headless storefronts

In case when you wanted to build a headless storefront for Magento, you would have considered three options:

  • use PWA Studio

  • use Vue Storefront

  • build custom frontend

In either case, the Magento 2 GraphQL API is a source of data, so let’s take a look hwo to retreive information about shipping methods from GraphQL and which data is available.

Fetch shipping methods from Magento GraphQL API

Create empty Cart

Firstly, we have to create an empty cart. To do so, send this mutation to the API:

mutation {
  createEmptyCart(input: {})
}

The mutation returns a new cart id like this:

{
  "data": {
    "createEmptyCart": "K9tlVNTGnyKk9b7Lw8xLnByORqQUhRGR"
  }
}

Add product to cart

Once we have a new cart, we can add products to it. Before we do that, we fetch information about products from Magento.

Fetch products information
query {
  products(search: "bag", pageSize: 5) {
    items {
      uid
      name
    }
  }
}

The query above returns five products that pass to the “bag” search term. The SKU field is important to us because we will use it in the next step. Here we have our five bags:

{
  "data": {
    "products": {
      "items": [
        {
          "sku": "24-MB01",
          "name": "Joust Duffle Bag"
        },
        {
          "sku": "24-WB01",
          "name": "Voyage Yoga Bag"
        },
        {
          "sku": "24-MB05",
          "name": "Wayfarer Messenger Bag"
        },
        {
          "sku": "24-WB04",
          "name": "Push It Messenger Bag"
        },
        {
          "sku": "24-UG03",
          "name": "Harmony Lumaflex™ Strength Band Kit "
        }
      ]
    }
  }
}
Add product to cart using addProductsToCartMutation

Once we know the cart ID, and some products IDs, we can add products to the cart:

mutation {
  addProductsToCart(cartId: "K9tlVNTGnyKk9b7Lw8xLnByORqQUhRGR", cartItems: [{ sku: "24-MB01", quantity: 1 }]) {
    cart {
      total_quantity
      items {
        product {
          sku
        }
      }
    }

  }
}

In the query above I added a product with SKU 24-Mb01 to the cart. Results:

{
  "data": {
    "addProductsToCart": {
      "cart": {
        "total_quantity": 1,
        "items": [
          {
            "product": {
              "sku": "24-MB01"
            }
          }
        ]
      }
    }
  }
}

Set shipping address on the cart

The shipping address is the last missing thing that we have to add to see available shipping methods. To add the shipping address we need to use the setShippingAddressesOnCart mutation:

mutation {
  setShippingAddressesOnCart(
    input: {
      cart_id: "K9tlVNTGnyKk9b7Lw8xLnByORqQUhRGR"
      shipping_addresses: [
        {
          address: {
            firstname: "Bob"
            lastname: "Roll"
            company: "Magento"
            street: ["Magento Pkwy", "Main Street"]
            city: "Austin"
            region: "TX"
            postcode: "78758"
            country_code: "US"
            telephone: "8675309"
            save_in_address_book: false
          }

        }
      ]
    }
  ) {
    cart {
      shipping_addresses {
        firstname
        lastname
        company
        street
        city
        region {
          code
          label
        }
        postcode
        telephone
        country {
          code
          label
        }
      }
    }
  }
}

When I send this mutation to the API, Magento will set the shipping address on the cart. Results:

{
  "data": {
    "setShippingAddressesOnCart": {
      "cart": {
        "shipping_addresses": [
          {
            "firstname": "Bob",
            "lastname": "Roll",
            "company": "Magento",
            "street": ["Magento Pkwy", "Main Street"],
            "city": "Austin",
            "region": {
              "code": "TX",
              "label": "Texas"
            },
            "postcode": "78758",
            "telephone": "8675309",
            "country": {
              "code": "US",
              "label": "US"
            }
          }
        ]
      }
    }
  }
}

Fetch available shipping methods from Magento 2 GraphQL API

We have everything to get information about shipping methods, so we can use this query:

query {
    cart(cart_id: "K9tlVNTGnyKk9b7Lw8xLnByORqQUhRGR") {
    	shipping_addresses {
        available_shipping_methods {
          amount {
            currency
            value
          }
          available
          carrier_code
          carrier_title
          error_message
          method_code
          method_title
          price_excl_tax {
            currency
            value
          }
          price_incl_tax {
            currency
            value
          }
        }
      }
    }
}

Magento returns available shipping methods, and as you can see below, all three mentioned earlier shipping methods (flat rate, table rate, and free shipping) are available:

{
  "data": {
    "cart": {
      "shipping_addresses": [
        {
          "available_shipping_methods": [
            {
              "amount": {
                "currency": "USD",
                "value": 0
              },
              "available": true,
              "carrier_code": "freeshipping",
              "carrier_title": "Free Shipping",
              "error_message": "",
              "method_code": "freeshipping",
              "method_title": "Free",
              "price_excl_tax": {
                "currency": "USD",
                "value": 0
              },
              "price_incl_tax": {
                "currency": "USD",
                "value": 0
              }
            },
            {
              "amount": {
                "currency": "USD",
                "value": 10
              },
              "available": true,
              "carrier_code": "flatrate",
              "carrier_title": "Flat Rate",
              "error_message": "",
              "method_code": "flatrate",
              "method_title": "Fixed",
              "price_excl_tax": {
                "currency": "USD",
                "value": 10
              },
              "price_incl_tax": {
                "currency": "USD",
                "value": 10
              }
            },
            {
              "amount": {
                "currency": "USD",
                "value": 15
              },
              "available": true,
              "carrier_code": "tablerate",
              "carrier_title": "Best Way",
              "error_message": "",
              "method_code": "bestway",
              "method_title": "Table Rate",
              "price_excl_tax": {
                "currency": "USD",
                "value": 15
              },
              "price_incl_tax": {
                "currency": "USD",
                "value": 15
              }
            }
          ]
        }
      ]
    }
  }
}

Support for shipping methods in GraphQL API and headless storefronts

Thanks to Magento 2 GraphQL API you can fetch information about basic delivery methods and use them on your headless storefront. Summarizing - these shipping methods:

  • flat rate

  • table rate

  • free shipping

are available in Vue Storefront, and PWA Studio, and they are easy to implement in custom storefronts.


How about other shipping methods?

Magento has a few other shipping methods:

  1. In-Store Delivery

  2. UPS

  3. USPS

  4. FedEx

  5. DHL

In-Store Delivery

The in-store delivery method allows choosing a pickup point when a customer wants to pick up an order. This feature is not supported in PWA STUDIO and Vue Storefront when I write this article.

Magento 2 GraphQL allows to set pickup point as a shipping address, and it’s possible to fetch pickup points by using the pickupLocations query so I assume that it’s possible to create custom code that covers this functionality in custom headless storefronts.

UPS, USPS, FedEx, DHL

No support in PWA Studio and Vue Storefront. Custom development is needed.


Custom shipping methods

What about custom shipping methods? You may ask: Is GraphQL return information about custom delivery methods among the default ones?

Just for test, I created a new delivery method called “Custom Delivery.”

You can find the Magento 2 module containing this delivery method on my Github.

It’s returned from API, and available in PWA Studio, and Vue Storefront as well.


Summary

Shipping methods are available for PWA Studio, Vue Storefront, and custom headless storefronts through GraphQL queries, and they are displayed on the storefront. Custom shipping methods also are shown as well. In-Store pickup and other methods than free shipping, flat rate, and table rate are not supported and custom development is needed. Anyway, for many clients, the default shipping methods are good enough and they can consider a headless storefront as a possible solution. I expect that in the future, the amount of supported shipping methods will be bigger, and maybe some extensions from external providers will be available.

Subscribe my blog