Can use the GraphQL API to create a Demo theme like the REST API?

Hi all, I want to create a demo theme in our app so that users can try out some features. If I use the REST API, there will be warnings and it may not pass the moderation step when uploading the theme to the Shopify app store.

I see some apps on the store have done this, but I think they are using the REST API
Now with the GraphQL API, what can I do?

My code:

// apiVersion: ApiVersion.January25
const responseDemo = await admin.graphql(
    `#graphql
    mutation UpdateThemeRole( $id: ID!, $role: ThemeRole! ) { // Try $input: ThemeInput! too
        themeUpdate( id: $id, input: { role: $role }) {
            theme {
                id
                role
                name
            }
            userErrors {
                field
                message
            }
        }
    }`,
    {
        variables: {
            'id': 'gid',
            'role': 'DEMO'
        }
    }
);

const installDemo = await responseDemo.json()

I got this error message:

"InputObject 'OnlineStoreThemeInput' doesn't accept argument 'role'"

My theme demo:

themeUpdate mutation can only update the name of the theme, not the role.

You need to use themeCreate mutation to create new theme. - themeCreate - GraphQL Admin

Hi, I tried the themeCreate mutation but it doesn’t accept the $role parameter, can you give me an example?

I think the new theme created using themeCreate mutation is always unpublished by default. You will need to use themePublish mutation to publish it.

I tried but it didn’t work, here is my code. Can you check it?

const response = await admin.graphql(
	`#graphql
	mutation themeCreate( $source: URL!, $name: String! ) {
		themeCreate( source: $source, name: $name ) {
			theme {
				id
				name
				role
			}
			userErrors {
				field
				message
			}
		}
	}`,
	{
		variables: {
			'source': 'themeUrl.zip',
			'role': 'DEMO',
			'name': 'My Theme Demo'
		}
	}
);

const installRes  = await response.json();
const responsePub = await admin.graphql(
	`#graphql
	mutation themePublish($id: ID!) {
		themePublish(id: $id) {
			theme {
				id
			}
			userErrors {
				code
				field
				message
			}
		}
	}`,
	{
		variables: {
			'id': installRes.data.themeCreate.theme.id
		}
	}
);

const pubRes = await responsePub.json();

My layout/theme.liquid file:

<!doctype html>
<html class="no-js" lang="{{ request.locale.iso_code }}">
	<head>
		{{ content_for_header }}

		{%- liquid
			echo 'style.css' | asset_url | stylesheet_tag

			render 'stylesheet'
			render 'meta'
		-%}
	</head>

	<body class="template-{{ template.name }}">
		<main id="main-content" class="content-for-layout" role="main" tabindex="-1">
			{{ content_for_layout }}
		</main>
	</body>
</html>

Error message:

"You can't publish this theme until the installation is complete. and Role can't be set to main: missing required file layout/theme.liquid"

Hey -can you try with a different theme (eg: fresh version of Dawn) to rule out that it’s something on the theme that’s blocking the mutation from working?

Hi, the problem here is not which theme, I think the problem is that I have a wrong approach to how the API works or the API does not support creating themes with role DEMO

But as Liam said, can you please try doing it with the Dawn theme, to rule anything out regarding the theme itself.

I tried with the latest Dawn theme on github and still got the same error. So the problem is not with my theme

Hey - digging into this a bit more, so the DEMO role is reserved for when you are previewing a theme from the Shopify Theme Store, before purchasing - you won’t be able to set a theme with this role to publish. Can you use a theme that doesn’t have this role?

Hey @Liam-Shopify @Luke
With the information I have provided, do you have any suggestions or recommendations for me?

@PeterParker Could you let me know if you found any solution?

Hi @Ronak_Panchal
Currently not possible, I still use REST API to do that and wait until it is fully migrated to Graphql

What would be the usecase for setting a theme to “demo” role? These are for themes on the Shopify Theme Store, to view as a preview before purchasing?

I noticed the ROLE field in the “2025-04 release candidate” version, but it only supports UNPUBLISHED and DEVELOPMENT roles. Unfortunately, I might have to implement it differently :sweat_smile: