Skip to content

Commit 9a75501

Browse files
authored
Merge pull request #1948 from Shopify/liz/add-scriptags-manager
[minor] Scrip tags manager
2 parents 49e2fb5 + 9dd884a commit 9a75501

File tree

14 files changed

+1098
-15
lines changed

14 files changed

+1098
-15
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
Unreleased
22
----------
3+
- Adds a `script_tag_manager` that will automatically create script tags when the app is installed. [1948](https://github.com/Shopify/shopify_app/pull/1948)
34

45
22.5.2 (March 14, 2025)
56
----------

app/controllers/shopify_app/callback_controller.rb

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ def perform_post_authenticate_jobs(session)
151151
session_for_shop = session.online? ? shop_session : session
152152

153153
install_webhooks(session_for_shop)
154-
154+
install_scripttags(session_for_shop)
155155
perform_after_authenticate_job(session)
156156
end
157157

@@ -161,6 +161,16 @@ def install_webhooks(session)
161161
WebhooksManager.queue(session.shop, session.access_token)
162162
end
163163

164+
def install_scripttags(session)
165+
return unless ShopifyApp.configuration.has_script_tags?
166+
167+
ScriptTagsManager.queue(
168+
session.shop,
169+
session.access_token,
170+
ShopifyApp.configuration.script_tags,
171+
)
172+
end
173+
164174
def perform_after_authenticate_job(session)
165175
config = ShopifyApp.configuration.after_authenticate_job
166176

docs/shopify_app/script-tags.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Script Tags
2+
3+
ShopifyApp can manage your app's [Script Tags](https://shopify.dev/docs/admin-api/graphql/reference/online-store/scripttag) for you by setting which script tags you require in the initializer.
4+
> [!NOTE]
5+
> Script tags should only be used for vintage themes that do not support app blocks.
6+
7+
## Configuration
8+
9+
```ruby
10+
ShopifyApp.configure do |config|
11+
config.script_tags = [
12+
# Basic script tag
13+
{cache: true, src: 'https://example.com/fancy.js'},
14+
15+
# Script tag with template_types for app block detection
16+
{
17+
cache: true,
18+
src: 'https://example.com/product-script.js',
19+
template_types: ['product', 'collection']
20+
}
21+
]
22+
end
23+
```
24+
25+
## Required Scopes
26+
Both the `write_script_tags` and `read_themes` scopes are required.
27+
28+
For apps created with the Shopify CLI, set these scopes in your `shopify.app.toml` file:
29+
30+
```toml
31+
[access_scopes]
32+
# Learn more at https://shopify.dev/docs/apps/tools/cli/configuration#access_scopes
33+
scopes = "write_products,write_script_tags,read_themes"
34+
```
35+
36+
For older apps, you can set the scopes in the initializer:
37+
38+
```ruby
39+
config.scope = 'write_products,write_script_tags,read_themes'
40+
```
41+
42+
## How It Works
43+
44+
### Script Tag Creation
45+
46+
Script tags are created in the same way as [Webhooks](/docs/shopify_app/webhooks.md), with a background job which will create the required scripttags.
47+
48+
### App Block Detection
49+
50+
When you specify `template_types` for a script tag, ShopifyApp will check if the store's active theme supports app blocks for those template types. If any template type doesn't support app blocks, the script tags will be created as a fallback
51+
52+
This allows your app to automatically adapt to the store's theme capabilities, using app blocks when available and falling back to script tags when necessary.

lib/shopify_app.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,11 @@ def self.use_webpacker?
6464

6565
# jobs
6666
require "shopify_app/jobs/webhooks_manager_job"
67+
require "shopify_app/jobs/script_tags_manager_job"
6768

6869
# managers
6970
require "shopify_app/managers/webhooks_manager"
70-
71+
require "shopify_app/managers/script_tags_manager"
7172
# middleware
7273
require "shopify_app/middleware/jwt_middleware"
7374

lib/shopify_app/auth/post_authenticate_tasks.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ def perform(session)
1010
session_for_shop = session.online? ? shop_session(session) : session
1111

1212
install_webhooks(session_for_shop)
13+
install_scripttags(session_for_shop)
1314

1415
perform_after_authenticate_job(session)
1516
end
@@ -27,6 +28,13 @@ def install_webhooks(session)
2728
WebhooksManager.queue(session.shop, session.access_token)
2829
end
2930

31+
def install_scripttags(session)
32+
ShopifyApp::Logger.debug("PostAuthenticateTasks: Installing scripttags")
33+
return unless ShopifyApp.configuration.has_script_tags?
34+
35+
ScriptTagsManager.queue(session.shop, session.access_token, ShopifyApp.configuration.script_tags)
36+
end
37+
3038
def perform_after_authenticate_job(session)
3139
ShopifyApp::Logger.debug("PostAuthenticateTasks: Performing after_authenticate_job")
3240
config = ShopifyApp.configuration.after_authenticate_job

lib/shopify_app/configuration.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class Configuration
1515
attr_accessor :embedded_app
1616
alias_method :embedded_app?, :embedded_app
1717
attr_accessor :webhooks
18-
attr_accessor :scripttags
18+
attr_accessor :script_tags
1919
attr_accessor :after_authenticate_job
2020
attr_accessor :api_version
2121

@@ -33,7 +33,7 @@ class Configuration
3333
attr_accessor :custom_post_authenticate_tasks
3434

3535
# customise ActiveJob queue names
36-
attr_accessor :scripttags_manager_queue_name
36+
attr_accessor :script_tags_manager_queue_name
3737
attr_accessor :webhooks_manager_queue_name
3838

3939
# configure myshopify domain for local shopify development
@@ -58,7 +58,7 @@ def initialize
5858
@root_url = "/"
5959
@myshopify_domain = "myshopify.com"
6060
@unified_admin_domain = "shopify.com"
61-
@scripttags_manager_queue_name = Rails.application.config.active_job.queue_name
61+
@script_tags_manager_queue_name = Rails.application.config.active_job.queue_name
6262
@webhooks_manager_queue_name = Rails.application.config.active_job.queue_name
6363
@disable_webpacker = ENV["SHOPIFY_APP_DISABLE_WEBPACKER"].present?
6464
@scope = []
@@ -115,8 +115,8 @@ def has_webhooks?
115115
webhooks.present?
116116
end
117117

118-
def has_scripttags?
119-
scripttags.present?
118+
def has_script_tags?
119+
script_tags.present?
120120
end
121121

122122
def requires_billing?

lib/shopify_app/controller_concerns/login_protection.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ def load_current_session(shopify_id_token: nil, cookies: nil, is_online: false)
269269
return ShopifyAPI::Context.load_private_session if ShopifyAPI::Context.private?
270270

271271
session_id = ShopifyAPI::Utils::SessionUtils.current_session_id(shopify_id_token, cookies, is_online)
272-
return nil unless session_id
272+
return unless session_id
273273

274274
ShopifyApp::SessionRepository.load_session(session_id)
275275
end

lib/shopify_app/engine.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ module RedactJobParams
55
private
66

77
def args_info(job)
8-
log_disabled_classes = ["ShopifyApp::WebhooksManagerJob"]
8+
log_disabled_classes = ["ShopifyApp::WebhooksManagerJob", "ShopifyApp::ScriptTagsManagerJob"]
99
return "" if log_disabled_classes.include?(job.class.name)
1010

1111
super
@@ -30,6 +30,7 @@ class Engine < Rails::Engine
3030
ActiveSupport.on_load(:active_job) do
3131
if ActiveJob::Base.respond_to?(:log_arguments?)
3232
WebhooksManagerJob.log_arguments = false
33+
ScriptTagsManagerJob.log_arguments = false
3334
elsif ActiveJob::Logging::LogSubscriber.private_method_defined?(:args_info)
3435
ActiveJob::Logging::LogSubscriber.prepend(RedactJobParams)
3536
end
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# frozen_string_literal: true
2+
3+
module ShopifyApp
4+
class ScriptTagsManagerJob < ActiveJob::Base
5+
queue_as do
6+
ShopifyApp.configuration.script_tags_manager_queue_name
7+
end
8+
9+
def perform(shop_domain:, shop_token:, script_tags:)
10+
ShopifyAPI::Auth::Session.temp(shop: shop_domain, access_token: shop_token) do |session|
11+
manager = ScriptTagsManager.new(script_tags, shop_domain)
12+
manager.create_script_tags(session: session)
13+
end
14+
end
15+
end
16+
end

0 commit comments

Comments
 (0)