Dedicated to the Hydrogen framework, headless commerce, and building custom storefronts using the Storefront API.
Hello,
I was wondering if there was a way to disable the shopify store front-end. I am currently using Shopify GraphQL API for a headless implementation with a react based front-end. I want to know If I can can link only the API (without Shopify's native front-end) to a sub.domain. Does anyone know if this is possible?
you can lock use of password protected
Yes absolutely you can use a subdomain for your headless site. You can also remove the Online Store channel by going to "manage channels" if you want to, but often folks redirect from it (if you ever had it published this can help with SEO/404s)
To learn more visit the Shopify Help Center or the Community Blog.
@vix can you please provide the article link here. or list of the steps
@vix I am currently using using Cloudflare to handle DNS. So ideally I would like like to redirect the root of my subdomain (shop.xxxx.com) to the homepage (xxxx.com/) and shop.xxxx.com/admin to Shopify admin. Can I do this with cloudflare?
You cannot put Cloudflare in front as Shopify is already using Cloudflare.
We have a headless storefront and some experience with this setup. I would advise against disabling the online shop sales channels as too much of the Shopify ecosystem relies on it's existence. So you're better off having a very minimal theme that redirects users to your headless store. However, you'll need to use a client side redirect.
The important part of our implementation looks something like code snippet below, note that we use the themes engine for account management and a few other features, so we're only redirecting some routes. We have multiple methods of redirect to ensure we catch it:
<!doctype html>
<html>
<head>
<title>{{ page_title }}</title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="description" content="{{ page_description | escape }}">
<link rel="canonical" href="{{ canonical_url }}">
<meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no">
{%- comment -%}
Detect what 'mode' the page is in. We cannot auto redirect under certain modes.
{%- endcomment -%}
{%- if content_for_header contains "previewBarInjector.init();" -%}
{%- assign page_mode = "preview" -%}
{%- elsif content_for_header contains "Shopify.designMode" or content_for_header contains 'editor_domain' -%}
{%- assign page_mode = "design" -%}
{%- else -%}
{%- assign page_mode = "live" -%}
{%- endif -%}
{%- comment -%}
## Headless router
Re-route to the headless store by assigning the redirect path to `headless_redirect_path`.
If a path is not assigned to then we will render the liquid template.
{%- endcomment -%}
{%- case request.page_type -%}
{% when "404" %}
{% when "article" %}
{% when "blog" %}
{% when "cart" %}
{% assign headless_redirect_path = "/cart" %}
{% when "collection" %}
{% assign headless_redirect_path = "" %}
{% when "list-collections" %}
{% assign headless_redirect_path = "" %}
{% when "customers/account" %}
{% when "customers/activate_account" %}
{% when "customers/addresses" %}
{% when "customers/login" %}
{% when "customers/order" %}
{% when "customers/register" %}
{% when "customers/reset_password" %}
{% when "gift_card" %}
{% when "index" %}
{% assign headless_redirect_path = "" %}
{% when "page" %}
{% when "password" %}
{% when "product" %}
{% assign headless_redirect_path = "/products/" | append: handle %}
{% when "search" %}
{% assign headless_redirect_path = "" %}
{% else %}
{%- endcase -%}
{%- assign headless_origin = settings.headless_origin -%}
{%- assign headless_redirect_base_url = settings.headless_redirect_base_url -%}
{%- comment -%} Construct the full headless path {%- endcomment -%}
{%- if headless_redirect_path and settings.headless_redirect_enabled == true -%}
{%- assign headless_redirect_url = headless_origin | append: headless_redirect_base_url | append: headless_redirect_path -%}
{% endif %}
{%- comment -%} We attempt a meta redirect, JS redirect with a fallback to an actual link. {%- endcomment -%}
{%- if headless_redirect_url -%}
{%- if page_mode == "live" -%}
<meta content="noindex" name="robots">
<script>
(function (){
var href = {{ headless_redirect_url | json }};
if (window.location.search) {
href += window.location.search;
}
if (window.location.hash) {
href += window.location.hash;
}
window.location.href = href;
})();
</script>
<style>
#headless-manual-redirect {
opacity: 0;
animation: delayFadeIn 500ms;
animation-delay: 2s;
animation-fill-mode: forwards;
}
@keyframes delayFadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
</style>
<meta content="1;url={{ headless_redirect_url }}" http-equiv="refresh">
{%- endif -%}
{%- else -%}
{%- comment -%}
Head for the themes engine
{%- endcomment -%}
{{ content_for_header }}
{%- endif -%}
</head>
<body class="site">
{%- if headless_redirect_url -%}
<div
id="headless-manual-redirect"
style="align-items: center; display: flex; flex-direction: column; height: 100vh; justify-content: center; width: 100%;">
<h1>{{ 'general.headless_redirect.title' | t }}</h1>
<p>
<a href="{{ headless_redirect_url }}">{{ 'general.headless_redirect.link' | t }}</a>
</p>
{%- if page_mode != "live" %}<em>auto-redirect from {{ headless_redirect_path }} to {{ headless_redirect_url }} skipped in {{ page_mode }} mode</em>{%- endif %}
</div>
{%- else -%}
{%- section 'site-header' -%}
<main role="main" class="site-content">
{{ content_for_layout }}
</main>
{%- section 'site-footer' -%}
{%- endif -%}
</body>
</html>
A few other lessons learnt the hard way:
Be aware that any apps that rely on Shopify URL structure will get it wrong. For example: Klaviyo, Drip, Facebook, Google Shopping, etc will all point to your themes engine. Some of them also do not like redirects, Google Shopping bans them.
If you're not using Multipass, you're probably better off using the themes engine for account management functionality as access via a customerAccessToken is not the same being authenticated. The user will not be authenticated on the Shopify Web Checkout.
We have our headless site on example.com and our store on subdomain.example.com. That way we can share analytics cookies between the two and it feels relatively seamless experience.
Access the graphql api via subdomain.example.com/api/version/graphql.json not via .myshopify.com domain, that way when the web checkout url will be on subdomain.example.com, not .myshopify.com. Same with abandoned cart emails.
Thanks for sharing this - really useful as it’s my first time setting up a headless Angular store.
Does this mean that you weren’t able to integrate with Facebook and Google shopping with this set up?
No you cannot remove the online store channel. Shopify is broken in that regard. if you want to use Hydrogen for example to run your own custom store you must have the Basic plan of better which requires the online store to be active. It just throws errors trying to delete. Hopefully Shopify will hire some real developers that will be able to fix this but in the meantime you have to use some hacks to deal with that bug. Its really sad to get this kind of response from Shopify Staff.
Ywtstewart
You can use Axios, JQuery Ajax or the Javascript Fetch API to get data from a store.
If you're using npm and want to use JQuery do npm i jquery first.
For example if the store url is myawesome-widgets.myshopify.com use:
$.ajax({
url: 'https://myawesome-widgets.myshopify.com/api/2020-10/graphql',
data: '{
productByHandle(handle: "<handle name>") {
id
}
}',
headers: 'X-Shopify-Storefront-Access-Token: <store token>'
}).done(data => {
console.log(data)
});
More detailed information here:
Maybe it is possible.