spree_google_analytics 1.0.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/assets/config/spree_google_analytics_manifest.js +4 -0
- data/app/controllers/spree_google_analytics/store_controller_decorator.rb +11 -0
- data/app/helpers/spree_google_analytics/base_helper.rb +188 -40
- data/app/javascript/spree_google_analytics/application.js +16 -0
- data/app/javascript/spree_google_analytics/controllers/spree_google_analytics_controller.js +4 -0
- data/app/models/spree/integrations/google_analytics.rb +5 -1
- data/app/views/spree/admin/integrations/forms/_google_analytics.html.erb +11 -4
- data/app/views/spree_google_analytics/_add_to_cart.html.erb +10 -4
- data/app/views/spree_google_analytics/_add_to_wishlist.erb +10 -4
- data/app/views/spree_google_analytics/_body_end.html.erb +50 -16
- data/app/views/spree_google_analytics/_body_start.html.erb +6 -0
- data/app/views/spree_google_analytics/_cart.html.erb +14 -6
- data/app/views/spree_google_analytics/_checkout_complete.html.erb +23 -9
- data/app/views/spree_google_analytics/_head.html.erb +49 -28
- data/app/views/spree_google_analytics/_product.html.erb +9 -3
- data/app/views/spree_google_analytics/_remove_from_cart.html.erb +10 -4
- data/config/importmap.rb +6 -0
- data/config/initializers/spree.rb +1 -0
- data/config/locales/en.yml +3 -0
- data/lib/spree_google_analytics/engine.rb +12 -1
- data/lib/spree_google_analytics/version.rb +1 -1
- metadata +6 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 19ff839e89a8bdedb1da8ed93fa302c690211e56ab199beaae23278d51178af8
|
|
4
|
+
data.tar.gz: c55371fada9e8c6d34b82f7bf05ceed492180b492e8b141bee7748846a46c207
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '0210987ac97d38ad1e72814a4eb391d2a887fea4af5c15ba429999b0d67ffe08da54d7f04b79a9f67445f7fcf36efa5137331209125e11fa288c30de4e2d35d7'
|
|
7
|
+
data.tar.gz: d777ce1865934d4739ec7c1c1c537b9e5b6987ffa88ba4accd47c5f0372281b8b8e8eb5564639b02d49365526a64cc60c3367633327fd60d1551cf4275e44e17
|
|
@@ -7,3 +7,14 @@ module SpreeGoogleAnalytics
|
|
|
7
7
|
end
|
|
8
8
|
|
|
9
9
|
Spree::StoreController.prepend(SpreeGoogleAnalytics::StoreControllerDecorator) if defined?(Spree::StoreController)
|
|
10
|
+
|
|
11
|
+
# include in Devise controllers
|
|
12
|
+
if defined?(Spree::UserSessionsController)
|
|
13
|
+
Spree::UserSessionsController.prepend(SpreeGoogleAnalytics::StoreControllerDecorator)
|
|
14
|
+
end
|
|
15
|
+
if defined?(Spree::UserRegistrationsController)
|
|
16
|
+
Spree::UserRegistrationsController.prepend(SpreeGoogleAnalytics::StoreControllerDecorator)
|
|
17
|
+
end
|
|
18
|
+
if defined?(Spree::UserPasswordsController)
|
|
19
|
+
Spree::UserPasswordsController.prepend(SpreeGoogleAnalytics::StoreControllerDecorator)
|
|
20
|
+
end
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
module SpreeGoogleAnalytics
|
|
2
2
|
module BaseHelper
|
|
3
|
-
def
|
|
4
|
-
|
|
3
|
+
def google_analytics_client_type
|
|
4
|
+
@google_analytics_client_type ||= store_integration('google_analytics')&.preferred_client
|
|
5
|
+
end
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
def use_gtm?
|
|
8
|
+
google_analytics_client_type == 'gtm'
|
|
7
9
|
end
|
|
8
10
|
|
|
9
11
|
def google_analytics_add_shipping_info_json(shipment)
|
|
@@ -21,60 +23,206 @@ module SpreeGoogleAnalytics
|
|
|
21
23
|
}.to_json.html_safe
|
|
22
24
|
end
|
|
23
25
|
|
|
24
|
-
def google_analytics_payment_json
|
|
25
|
-
return unless @order.present?
|
|
26
|
-
|
|
27
|
-
@google_analytics_payment_json ||= SpreeGoogleAnalytics::PaymentPresenter.new(order: @order).call.to_json.html_safe
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def google_analytics_purchase_json
|
|
31
|
-
return unless @order.present?
|
|
32
26
|
|
|
33
|
-
@google_analytics_purchase_json ||= SpreeGoogleAnalytics::OrderPresenter.new(order: @order).call.to_json.html_safe
|
|
34
|
-
end
|
|
35
27
|
|
|
36
28
|
def google_analytics_view_item_json(variant = nil)
|
|
37
29
|
variant ||= @selected_variant || @variant_from_options || @product&.default_variant
|
|
38
30
|
return unless variant.present?
|
|
39
31
|
|
|
32
|
+
if use_gtm?
|
|
33
|
+
google_analytics_gtm_view_item_json(variant)
|
|
34
|
+
else
|
|
35
|
+
{
|
|
36
|
+
currency: current_currency,
|
|
37
|
+
value: variant.amount_in(current_currency).to_f,
|
|
38
|
+
items: [
|
|
39
|
+
SpreeGoogleAnalytics::ProductPresenter.new(
|
|
40
|
+
store_name: current_store.name,
|
|
41
|
+
resource: variant,
|
|
42
|
+
quantity: 1
|
|
43
|
+
).call
|
|
44
|
+
]
|
|
45
|
+
}.to_json.html_safe
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def google_analytics_gtm_view_item_json(variant)
|
|
40
50
|
{
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
51
|
+
event: 'view_item',
|
|
52
|
+
ecommerce: {
|
|
53
|
+
currency: current_currency,
|
|
54
|
+
value: variant.amount_in(current_currency).to_f,
|
|
55
|
+
items: [
|
|
56
|
+
SpreeGoogleAnalytics::ProductPresenter.new(
|
|
57
|
+
store_name: current_store.name,
|
|
58
|
+
resource: variant,
|
|
59
|
+
quantity: 1
|
|
60
|
+
).call
|
|
61
|
+
]
|
|
62
|
+
}
|
|
50
63
|
}.to_json.html_safe
|
|
51
64
|
end
|
|
52
65
|
|
|
53
66
|
def google_analytics_cart_event_json(line_item, quantity, position)
|
|
67
|
+
if use_gtm?
|
|
68
|
+
google_analytics_gtm_cart_event_json(line_item, quantity, position)
|
|
69
|
+
else
|
|
70
|
+
{
|
|
71
|
+
currency: line_item.currency,
|
|
72
|
+
value: line_item.amount.to_f,
|
|
73
|
+
items: [
|
|
74
|
+
SpreeGoogleAnalytics::ProductPresenter.new(
|
|
75
|
+
resource: line_item,
|
|
76
|
+
quantity: quantity,
|
|
77
|
+
position: position
|
|
78
|
+
).call
|
|
79
|
+
]
|
|
80
|
+
}.to_json.html_safe
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def google_analytics_gtm_cart_event_json(line_item, quantity, position)
|
|
85
|
+
{
|
|
86
|
+
event: 'add_to_cart',
|
|
87
|
+
ecommerce: {
|
|
88
|
+
currency: line_item.currency,
|
|
89
|
+
value: line_item.amount.to_f,
|
|
90
|
+
items: [
|
|
91
|
+
SpreeGoogleAnalytics::ProductPresenter.new(
|
|
92
|
+
resource: line_item,
|
|
93
|
+
quantity: quantity,
|
|
94
|
+
position: position
|
|
95
|
+
).call
|
|
96
|
+
]
|
|
97
|
+
}
|
|
98
|
+
}.to_json.html_safe
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def google_analytics_remove_from_cart_event_json(line_item, quantity, position)
|
|
102
|
+
if use_gtm?
|
|
103
|
+
google_analytics_gtm_remove_from_cart_event_json(line_item, quantity, position)
|
|
104
|
+
else
|
|
105
|
+
google_analytics_cart_event_json(line_item, quantity, position)
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def google_analytics_gtm_remove_from_cart_event_json(line_item, quantity, position)
|
|
54
110
|
{
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
111
|
+
event: 'remove_from_cart',
|
|
112
|
+
ecommerce: {
|
|
113
|
+
currency: line_item.currency,
|
|
114
|
+
value: line_item.amount.to_f,
|
|
115
|
+
items: [
|
|
116
|
+
SpreeGoogleAnalytics::ProductPresenter.new(
|
|
117
|
+
resource: line_item,
|
|
118
|
+
quantity: quantity,
|
|
119
|
+
position: position
|
|
120
|
+
).call
|
|
121
|
+
]
|
|
122
|
+
}
|
|
64
123
|
}.to_json.html_safe
|
|
65
124
|
end
|
|
66
125
|
|
|
67
126
|
def google_analytics_add_to_wishlist_event_json(variant)
|
|
127
|
+
if use_gtm?
|
|
128
|
+
google_analytics_gtm_add_to_wishlist_event_json(variant)
|
|
129
|
+
else
|
|
130
|
+
{
|
|
131
|
+
currency: current_currency,
|
|
132
|
+
value: variant.amount_in(current_currency),
|
|
133
|
+
items: [
|
|
134
|
+
SpreeGoogleAnalytics::ProductPresenter.new(
|
|
135
|
+
store_name: current_store.name,
|
|
136
|
+
resource: variant,
|
|
137
|
+
quantity: 1
|
|
138
|
+
).call
|
|
139
|
+
]
|
|
140
|
+
}.to_json.html_safe
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def google_analytics_gtm_add_to_wishlist_event_json(variant)
|
|
68
145
|
{
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
146
|
+
event: 'add_to_wishlist',
|
|
147
|
+
ecommerce: {
|
|
148
|
+
currency: current_currency,
|
|
149
|
+
value: variant.amount_in(current_currency),
|
|
150
|
+
items: [
|
|
151
|
+
SpreeGoogleAnalytics::ProductPresenter.new(
|
|
152
|
+
store_name: current_store.name,
|
|
153
|
+
resource: variant,
|
|
154
|
+
quantity: 1
|
|
155
|
+
).call
|
|
156
|
+
]
|
|
157
|
+
}
|
|
158
|
+
}.to_json.html_safe
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def google_analytics_checkout_json
|
|
162
|
+
return unless @order.present?
|
|
163
|
+
|
|
164
|
+
if use_gtm?
|
|
165
|
+
google_analytics_gtm_checkout_json
|
|
166
|
+
else
|
|
167
|
+
@google_analytics_checkout_json ||= SpreeGoogleAnalytics::CheckoutPresenter.new(order: @order).call.to_json.html_safe
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def google_analytics_gtm_checkout_json
|
|
172
|
+
@google_analytics_gtm_checkout_json ||= {
|
|
173
|
+
event: 'begin_checkout',
|
|
174
|
+
ecommerce: SpreeGoogleAnalytics::CheckoutPresenter.new(order: @order).call
|
|
175
|
+
}.to_json.html_safe
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def google_analytics_purchase_json
|
|
179
|
+
return unless @order.present?
|
|
180
|
+
|
|
181
|
+
if use_gtm?
|
|
182
|
+
google_analytics_gtm_purchase_json
|
|
183
|
+
else
|
|
184
|
+
@google_analytics_purchase_json ||= SpreeGoogleAnalytics::OrderPresenter.new(order: @order).call.to_json.html_safe
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def google_analytics_gtm_purchase_json
|
|
189
|
+
@google_analytics_gtm_purchase_json ||= {
|
|
190
|
+
event: 'purchase',
|
|
191
|
+
ecommerce: SpreeGoogleAnalytics::OrderPresenter.new(order: @order).call
|
|
192
|
+
}.to_json.html_safe
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def google_analytics_payment_json
|
|
196
|
+
return unless @order.present?
|
|
197
|
+
|
|
198
|
+
if use_gtm?
|
|
199
|
+
google_analytics_gtm_payment_json
|
|
200
|
+
else
|
|
201
|
+
@google_analytics_payment_json ||= SpreeGoogleAnalytics::PaymentPresenter.new(order: @order).call.to_json.html_safe
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def google_analytics_gtm_payment_json
|
|
206
|
+
@google_analytics_gtm_payment_json ||= {
|
|
207
|
+
event: 'add_payment_info',
|
|
208
|
+
ecommerce: SpreeGoogleAnalytics::PaymentPresenter.new(order: @order).call
|
|
209
|
+
}.to_json.html_safe
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
def google_analytics_view_cart_json
|
|
213
|
+
return unless @order.present?
|
|
214
|
+
|
|
215
|
+
if use_gtm?
|
|
216
|
+
google_analytics_gtm_view_cart_json
|
|
217
|
+
else
|
|
218
|
+
@google_analytics_view_cart_json ||= SpreeGoogleAnalytics::CheckoutPresenter.new(order: @order).call.to_json.html_safe
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
def google_analytics_gtm_view_cart_json
|
|
223
|
+
@google_analytics_gtm_view_cart_json ||= {
|
|
224
|
+
event: 'view_cart',
|
|
225
|
+
ecommerce: SpreeGoogleAnalytics::CheckoutPresenter.new(order: @order).call
|
|
78
226
|
}.to_json.html_safe
|
|
79
227
|
end
|
|
80
228
|
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import '@hotwired/turbo-rails'
|
|
2
|
+
import { Application } from '@hotwired/stimulus'
|
|
3
|
+
|
|
4
|
+
let application
|
|
5
|
+
|
|
6
|
+
if (typeof window.Stimulus === "undefined") {
|
|
7
|
+
application = Application.start()
|
|
8
|
+
application.debug = false
|
|
9
|
+
window.Stimulus = application
|
|
10
|
+
} else {
|
|
11
|
+
application = window.Stimulus
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
import SpreeGoogleAnalyticsController from 'spree_google_analytics/controllers/spree_google_analytics_controller'
|
|
15
|
+
|
|
16
|
+
application.register('spree_google_analytics', SpreeGoogleAnalyticsController)
|
|
@@ -2,8 +2,12 @@ module Spree
|
|
|
2
2
|
module Integrations
|
|
3
3
|
class GoogleAnalytics < Spree::Integration
|
|
4
4
|
preference :measurement_id, :string
|
|
5
|
+
preference :google_tag_manager_id, :string
|
|
6
|
+
preference :client, :string, default: 'ga4'
|
|
5
7
|
|
|
6
|
-
validates :preferred_measurement_id, presence: true
|
|
8
|
+
validates :preferred_measurement_id, presence: true, if: -> { preferred_client == 'ga4' }
|
|
9
|
+
validates :preferred_google_tag_manager_id, presence: true, if: -> { preferred_client == 'gtm' }
|
|
10
|
+
validates :preferred_client, inclusion: { in: %w[ga4 gtm] }
|
|
7
11
|
|
|
8
12
|
def self.integration_group
|
|
9
13
|
'analytics'
|
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
<div class="card mb-4">
|
|
2
|
-
<div class="card-body">
|
|
2
|
+
<div class="card-body" data-controller="reveal">
|
|
3
3
|
<% if @integration.persisted? %>
|
|
4
4
|
<div class="alert alert-warning">
|
|
5
5
|
<%= Spree.t('admin.integrations.google_analytics.reports_warning') %>
|
|
6
6
|
</div>
|
|
7
7
|
<% end %>
|
|
8
8
|
|
|
9
|
-
<%=
|
|
10
|
-
|
|
9
|
+
<%= form.spree_collection_select "preferred_client", [['Google Analytics 4', 'ga4'], ['Google Tag Manager', 'gtm']], :last, :first, { selected: @integration.preferred_client, label: Spree.t('admin.integrations.google_analytics.client'), help: Spree.t('admin.integrations.google_analytics.client_help') }, { data: { action: 'change->reveal#toggle' } } %>
|
|
10
|
+
|
|
11
|
+
<div data-reveal-target="item">
|
|
12
|
+
<%= preference_field(@integration, form, 'measurement_id', i18n_scope: 'admin.integrations.google_analytics') %>
|
|
11
13
|
<%= external_link_to 'Where to find my Measurement ID?', 'https://support.google.com/analytics/answer/12270356' %>
|
|
12
|
-
</
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
<div class="hidden" data-reveal-target="item">
|
|
17
|
+
<%= preference_field(@integration, form, 'google_tag_manager_id', i18n_scope: 'admin.integrations.google_analytics') %>
|
|
18
|
+
<%= external_link_to 'Where to find my Google Tag Manager ID?', 'https://support.google.com/tagmanager/answer/6107028' %>
|
|
19
|
+
</div>
|
|
13
20
|
</div>
|
|
14
21
|
</div>
|
|
15
22
|
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
<% if store_integration('google_analytics').present? %>
|
|
2
2
|
<script>
|
|
3
|
-
|
|
4
|
-
<%
|
|
5
|
-
|
|
3
|
+
<% safely do %>
|
|
4
|
+
<% if use_gtm? %>
|
|
5
|
+
if (window.dataLayer) {
|
|
6
|
+
dataLayer.push(<%= google_analytics_cart_event_json(@line_item, @line_item.quantity, @order.line_items.pluck(:id).index(@line_item.id) + 1) %>);
|
|
7
|
+
}
|
|
8
|
+
<% else %>
|
|
9
|
+
if (window.gtag) {
|
|
10
|
+
gtag('event', 'add_to_cart', <%= google_analytics_cart_event_json(@line_item, @line_item.quantity, @order.line_items.pluck(:id).index(@line_item.id) + 1) %>);
|
|
11
|
+
}
|
|
6
12
|
<% end %>
|
|
7
|
-
|
|
13
|
+
<% end %>
|
|
8
14
|
</script>
|
|
9
15
|
<% end %>
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
<% if store_integration('google_analytics').present? && @wished_item&.variant.present? %>
|
|
2
2
|
<script>
|
|
3
|
-
|
|
4
|
-
<%
|
|
5
|
-
|
|
3
|
+
<% safely do %>
|
|
4
|
+
<% if use_gtm? %>
|
|
5
|
+
if (window.dataLayer) {
|
|
6
|
+
dataLayer.push(<%= google_analytics_add_to_wishlist_event_json(@wished_item.variant) %>);
|
|
7
|
+
}
|
|
8
|
+
<% else %>
|
|
9
|
+
if (window.gtag) {
|
|
10
|
+
gtag('event', 'add_to_wishlist', <%= google_analytics_add_to_wishlist_event_json(@wished_item.variant) %>);
|
|
11
|
+
}
|
|
6
12
|
<% end %>
|
|
7
|
-
|
|
13
|
+
<% end %>
|
|
8
14
|
</script>
|
|
9
15
|
<% end %>
|
|
@@ -1,27 +1,61 @@
|
|
|
1
1
|
<% if store_integration('google_analytics').present? %>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
<% if
|
|
6
|
-
<%
|
|
7
|
-
|
|
2
|
+
<% if use_gtm? %>
|
|
3
|
+
<script>
|
|
4
|
+
if (window.dataLayer) {
|
|
5
|
+
<% if controller_name == 'checkout' %>
|
|
6
|
+
<% if @order && session[:checkout_started] %>
|
|
7
|
+
<% safely do %>
|
|
8
|
+
dataLayer.push(<%= google_analytics_checkout_json %>);
|
|
9
|
+
<% end %>
|
|
10
|
+
<% end %>
|
|
11
|
+
|
|
12
|
+
<% if @order && session[:checkout_step_completed] == 'delivery' %>
|
|
13
|
+
<% safely do %>
|
|
14
|
+
<% @order.shipments.each do |shipment| %>
|
|
15
|
+
dataLayer.push({
|
|
16
|
+
event: 'add_shipping_info',
|
|
17
|
+
ecommerce: <%= google_analytics_add_shipping_info_json(shipment) %>
|
|
18
|
+
});
|
|
19
|
+
<% end %>
|
|
20
|
+
<% end %>
|
|
8
21
|
<% end %>
|
|
9
22
|
<% end %>
|
|
10
23
|
|
|
11
|
-
<% if
|
|
24
|
+
<% if controller_name == 'search' && action_name == 'show' && query.present? %>
|
|
12
25
|
<% safely do %>
|
|
13
|
-
|
|
14
|
-
|
|
26
|
+
dataLayer.push({
|
|
27
|
+
event: 'search',
|
|
28
|
+
search_term: "<%= ERB::Util.html_escape(query) %>"
|
|
29
|
+
});
|
|
30
|
+
<% end %>
|
|
31
|
+
<% end %>
|
|
32
|
+
}
|
|
33
|
+
</script>
|
|
34
|
+
<% else %>
|
|
35
|
+
<script>
|
|
36
|
+
if (window.gtag) {
|
|
37
|
+
<% if controller_name == 'checkout' %>
|
|
38
|
+
<% if @order && session[:checkout_started] %>
|
|
39
|
+
<% safely do %>
|
|
40
|
+
gtag('event', 'begin_checkout', <%= google_analytics_checkout_json %>);
|
|
41
|
+
<% end %>
|
|
42
|
+
<% end %>
|
|
43
|
+
|
|
44
|
+
<% if @order && session[:checkout_step_completed] == 'delivery' %>
|
|
45
|
+
<% safely do %>
|
|
46
|
+
<% @order.shipments.each do |shipment| %>
|
|
47
|
+
gtag('event', 'add_shipping_info', <%= google_analytics_add_shipping_info_json(shipment) %>);
|
|
48
|
+
<% end %>
|
|
15
49
|
<% end %>
|
|
16
50
|
<% end %>
|
|
17
51
|
<% end %>
|
|
18
|
-
<% end %>
|
|
19
52
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
53
|
+
<% if controller_name == 'search' && action_name == 'show' && query.present? %>
|
|
54
|
+
<% safely do %>
|
|
55
|
+
gtag('event', 'search', <%= raw({ search_term: ERB::Util.html_escape(query) }.to_json) %>);
|
|
56
|
+
<% end %>
|
|
23
57
|
<% end %>
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
58
|
+
}
|
|
59
|
+
</script>
|
|
60
|
+
<% end %>
|
|
27
61
|
<% end %>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<% if store_integration('google_analytics').present? && use_gtm? %>
|
|
2
|
+
<!-- Google Tag Manager (noscript) -->
|
|
3
|
+
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=<%= store_integration('google_analytics').preferred_google_tag_manager_id %>"
|
|
4
|
+
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
|
|
5
|
+
<!-- End Google Tag Manager (noscript) -->
|
|
6
|
+
<% end %>
|
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
<% if store_integration('google_analytics').present? %>
|
|
2
2
|
<script>
|
|
3
|
-
if
|
|
4
|
-
<% if
|
|
5
|
-
window.
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
<% if @order.present? && @line_items.any? %>
|
|
4
|
+
<% if use_gtm? %>
|
|
5
|
+
if (window.dataLayer) {
|
|
6
|
+
window.addEventListener('slideover:open', () => {
|
|
7
|
+
dataLayer.push(<%= google_analytics_view_cart_json %>);
|
|
8
|
+
})
|
|
9
|
+
}
|
|
10
|
+
<% else %>
|
|
11
|
+
if (window.gtag) {
|
|
12
|
+
window.addEventListener('slideover:open', () => {
|
|
13
|
+
gtag('event', 'view_cart', <%= google_analytics_view_cart_json %>);
|
|
14
|
+
})
|
|
15
|
+
}
|
|
8
16
|
<% end %>
|
|
9
|
-
|
|
17
|
+
<% end %>
|
|
10
18
|
</script>
|
|
11
19
|
<% end %>
|
|
@@ -1,15 +1,29 @@
|
|
|
1
1
|
<% if store_integration('google_analytics').present? %>
|
|
2
2
|
<script>
|
|
3
|
-
|
|
4
|
-
<%
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
<% safely do %>
|
|
4
|
+
<% if use_gtm? %>
|
|
5
|
+
if (window.dataLayer) {
|
|
6
|
+
<% if @order.user.present? %>
|
|
7
|
+
dataLayer.push({
|
|
8
|
+
user_id: "<%= @order.reload.user_id %>",
|
|
9
|
+
user_properties: <%= google_analytics_user_properties_json(@order.user) %>
|
|
10
|
+
});
|
|
11
|
+
<% end %>
|
|
9
12
|
|
|
10
|
-
|
|
11
|
-
|
|
13
|
+
dataLayer.push(<%= google_analytics_payment_json %>);
|
|
14
|
+
dataLayer.push(<%= google_analytics_purchase_json %>);
|
|
15
|
+
}
|
|
16
|
+
<% else %>
|
|
17
|
+
if (window.gtag) {
|
|
18
|
+
<% if @order.user.present? %>
|
|
19
|
+
gtag('set', 'user_id', "<%= @order.reload.user_id %>");
|
|
20
|
+
gtag('set', 'user_properties', <%= google_analytics_user_properties_json(@order.user) %>);
|
|
21
|
+
<% end %>
|
|
22
|
+
|
|
23
|
+
gtag('event', 'add_payment_info', <%= google_analytics_payment_json %>);
|
|
24
|
+
gtag('event', 'purchase', <%= google_analytics_purchase_json %>);
|
|
25
|
+
}
|
|
12
26
|
<% end %>
|
|
13
|
-
|
|
27
|
+
<% end %>
|
|
14
28
|
</script>
|
|
15
29
|
<% end %>
|
|
@@ -1,34 +1,55 @@
|
|
|
1
1
|
<% if store_integration('google_analytics').present? %>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
<% if use_gtm? %>
|
|
3
|
+
<!-- Google Tag Manager -->
|
|
4
|
+
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
|
|
5
|
+
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
|
|
6
|
+
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
|
|
7
|
+
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
|
|
8
|
+
})(window,document,'script','dataLayer','<%= store_integration('google_analytics').preferred_google_tag_manager_id %>');</script>
|
|
9
|
+
<!-- End Google Tag Manager -->
|
|
10
|
+
|
|
11
|
+
<script>
|
|
12
|
+
window.dataLayer = window.dataLayer || [];
|
|
13
|
+
|
|
14
|
+
<% if try_spree_current_user %>
|
|
15
|
+
dataLayer.push({
|
|
16
|
+
user_id: "<%= try_spree_current_user.id %>",
|
|
17
|
+
user_properties: <%= google_analytics_user_properties_json(try_spree_current_user) %>
|
|
18
|
+
});
|
|
19
|
+
<% end %>
|
|
20
|
+
</script>
|
|
21
|
+
<% else %>
|
|
22
|
+
<!-- Google tag (gtag.js) -->
|
|
23
|
+
<script async src="https://www.googletagmanager.com/gtag/js?id=<%= store_integration('google_analytics').preferred_measurement_id %>"></script>
|
|
24
|
+
<script>
|
|
25
|
+
window.dataLayer = window.dataLayer || [];
|
|
26
|
+
function gtag(){dataLayer.push(arguments);}
|
|
7
27
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
28
|
+
<% if defined?(store_integration('cookie_first')) && store_integration('cookie_first').present? %>
|
|
29
|
+
gtag('consent', 'default', {
|
|
30
|
+
'ad_storage': 'denied',
|
|
31
|
+
'ad_user_data': 'denied',
|
|
32
|
+
'ad_personalization': 'denied',
|
|
33
|
+
'analytics_storage': 'denied',
|
|
34
|
+
'functionality_storage': 'denied',
|
|
35
|
+
'security_storage': 'granted',
|
|
36
|
+
'wait_for_update': 2000
|
|
37
|
+
});
|
|
38
|
+
<% end %>
|
|
19
39
|
|
|
20
|
-
|
|
21
|
-
|
|
40
|
+
gtag('js', new Date());
|
|
41
|
+
GA_MEASUREMENT_ID = "<%= store_integration('google_analytics').preferred_measurement_id %>";
|
|
22
42
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
43
|
+
<% if ENV['GA_DEBUG_MODE'].present? %>
|
|
44
|
+
gtag('config', GA_MEASUREMENT_ID, { "debug_mode": true });
|
|
45
|
+
<% else %>
|
|
46
|
+
gtag('config', GA_MEASUREMENT_ID);
|
|
47
|
+
<% end %>
|
|
28
48
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
49
|
+
<% if try_spree_current_user %>
|
|
50
|
+
gtag('set', 'user_id', "<%= try_spree_current_user.id %>");
|
|
51
|
+
gtag('set', 'user_properties', <%= google_analytics_user_properties_json(try_spree_current_user) %>);
|
|
52
|
+
<% end %>
|
|
53
|
+
</script>
|
|
54
|
+
<% end %>
|
|
34
55
|
<% end %>
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
<% if store_integration('google_analytics').present? %>
|
|
2
2
|
<script>
|
|
3
|
-
if
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
<% if use_gtm? %>
|
|
4
|
+
if (window.dataLayer) {
|
|
5
|
+
dataLayer.push(<%= google_analytics_view_item_json %>);
|
|
6
|
+
}
|
|
7
|
+
<% else %>
|
|
8
|
+
if (window.gtag) {
|
|
9
|
+
gtag('event', 'view_item', <%= google_analytics_view_item_json %>);
|
|
10
|
+
}
|
|
11
|
+
<% end %>
|
|
6
12
|
</script>
|
|
7
13
|
<% end %>
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
<% if store_integration('google_analytics').present? %>
|
|
2
2
|
<script>
|
|
3
|
-
|
|
4
|
-
<%
|
|
5
|
-
|
|
3
|
+
<% safely do %>
|
|
4
|
+
<% if use_gtm? %>
|
|
5
|
+
if (window.dataLayer) {
|
|
6
|
+
dataLayer.push(<%= google_analytics_remove_from_cart_event_json(@line_item, @line_item.quantity, nil) %>);
|
|
7
|
+
}
|
|
8
|
+
<% else %>
|
|
9
|
+
if (window.gtag) {
|
|
10
|
+
gtag('event', 'remove_from_cart', <%= google_analytics_remove_from_cart_event_json(@line_item, @line_item.quantity, nil) %>);
|
|
11
|
+
}
|
|
6
12
|
<% end %>
|
|
7
|
-
|
|
13
|
+
<% end %>
|
|
8
14
|
</script>
|
|
9
15
|
<% end %>
|
data/config/importmap.rb
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
pin 'application-spree_google_analytics', to: 'spree_google_analytics/application.js', preload: false
|
|
2
|
+
|
|
3
|
+
pin_all_from SpreeGoogleAnalytics::Engine.root.join('app/javascript/spree_google_analytics/controllers'),
|
|
4
|
+
under: 'spree_google_analytics/controllers',
|
|
5
|
+
to: 'spree_google_analytics/controllers',
|
|
6
|
+
preload: 'application-spree_google_analytics'
|
|
@@ -3,6 +3,7 @@ Rails.application.config.after_initialize do
|
|
|
3
3
|
|
|
4
4
|
if Rails.application.config.respond_to?(:spree_storefront)
|
|
5
5
|
Rails.application.config.spree_storefront.head_partials << 'spree_google_analytics/head'
|
|
6
|
+
Rails.application.config.spree_storefront.body_start_partials << 'spree_google_analytics/body_start'
|
|
6
7
|
Rails.application.config.spree_storefront.body_end_partials << 'spree_google_analytics/body_end'
|
|
7
8
|
|
|
8
9
|
Rails.application.config.spree_storefront.cart_partials << 'spree_google_analytics/cart'
|
data/config/locales/en.yml
CHANGED
|
@@ -8,3 +8,6 @@ en:
|
|
|
8
8
|
reports_warning: It can take up to 48 hours for the data to appear in standard reports
|
|
9
9
|
measurement_id: Measurement ID
|
|
10
10
|
api_secret: API Secret
|
|
11
|
+
google_tag_manager_id: Google Tag Manager ID
|
|
12
|
+
client: Client Type
|
|
13
|
+
client_help: Choose between Google Analytics 4 (direct gtag.js implementation) or Google Tag Manager (dataLayer events)
|
|
@@ -14,7 +14,18 @@ module SpreeGoogleAnalytics
|
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
initializer 'spree_google_analytics.assets' do |app|
|
|
17
|
-
app.config.assets
|
|
17
|
+
if app.config.respond_to?(:assets)
|
|
18
|
+
app.config.assets.paths << root.join('app/javascript')
|
|
19
|
+
app.config.assets.paths << root.join('vendor/javascript')
|
|
20
|
+
app.config.assets.paths << root.join('vendor/stylesheets')
|
|
21
|
+
app.config.assets.precompile += %w[spree_google_analytics_manifest]
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
initializer 'spree_google_analytics.importmap', before: 'importmap' do |app|
|
|
26
|
+
app.config.importmap.paths << root.join('config/importmap.rb')
|
|
27
|
+
# https://github.com/rails/importmap-rails?tab=readme-ov-file#sweeping-the-cache-in-development-and-test
|
|
28
|
+
app.config.importmap.cache_sweepers << root.join('app/javascript')
|
|
18
29
|
end
|
|
19
30
|
|
|
20
31
|
def self.activate
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: spree_google_analytics
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0
|
|
4
|
+
version: 1.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Vendo Connect Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-
|
|
11
|
+
date: 2025-11-06 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: spree
|
|
@@ -79,6 +79,8 @@ files:
|
|
|
79
79
|
- app/assets/images/integration_icons/google-analytics-logo.png
|
|
80
80
|
- app/controllers/spree_google_analytics/store_controller_decorator.rb
|
|
81
81
|
- app/helpers/spree_google_analytics/base_helper.rb
|
|
82
|
+
- app/javascript/spree_google_analytics/application.js
|
|
83
|
+
- app/javascript/spree_google_analytics/controllers/spree_google_analytics_controller.js
|
|
82
84
|
- app/models/spree/integrations/google_analytics.rb
|
|
83
85
|
- app/presenters/spree_google_analytics/checkout_presenter.rb
|
|
84
86
|
- app/presenters/spree_google_analytics/order_presenter.rb
|
|
@@ -88,11 +90,13 @@ files:
|
|
|
88
90
|
- app/views/spree_google_analytics/_add_to_cart.html.erb
|
|
89
91
|
- app/views/spree_google_analytics/_add_to_wishlist.erb
|
|
90
92
|
- app/views/spree_google_analytics/_body_end.html.erb
|
|
93
|
+
- app/views/spree_google_analytics/_body_start.html.erb
|
|
91
94
|
- app/views/spree_google_analytics/_cart.html.erb
|
|
92
95
|
- app/views/spree_google_analytics/_checkout_complete.html.erb
|
|
93
96
|
- app/views/spree_google_analytics/_head.html.erb
|
|
94
97
|
- app/views/spree_google_analytics/_product.html.erb
|
|
95
98
|
- app/views/spree_google_analytics/_remove_from_cart.html.erb
|
|
99
|
+
- config/importmap.rb
|
|
96
100
|
- config/initializers/spree.rb
|
|
97
101
|
- config/locales/en.yml
|
|
98
102
|
- config/routes.rb
|