diff --git a/app/helpers/mascot_helper.rb b/app/helpers/mascot_helper.rb
index 8ee04383e..34b656411 100644
--- a/app/helpers/mascot_helper.rb
+++ b/app/helpers/mascot_helper.rb
@@ -2,7 +2,7 @@
 
 module MascotHelper
   def mascot_url
-    full_asset_url(instance_presenter.mascot&.file&.url || asset_pack_path('media/images/elephant_ui_plane.svg'))
+    full_asset_url(instance_presenter.mascot&.file&.url || frontend_asset_path('images/elephant_ui_plane.svg'))
   end
 
   def instance_presenter
diff --git a/app/helpers/routing_helper.rb b/app/helpers/routing_helper.rb
index 2fb9ce72c..15d988f64 100644
--- a/app/helpers/routing_helper.rb
+++ b/app/helpers/routing_helper.rb
@@ -24,8 +24,12 @@ module RoutingHelper
     Rails.configuration.action_controller.asset_host || root_url
   end
 
-  def full_pack_url(source, **options)
-    full_asset_url(asset_pack_path(source, **options))
+  def frontend_asset_path(source, **options)
+    asset_pack_path("media/#{source}", **options)
+  end
+
+  def frontend_asset_url(source, **options)
+    full_asset_url(frontend_asset_path(source, **options))
   end
 
   def use_storage?
diff --git a/app/serializers/manifest_serializer.rb b/app/serializers/manifest_serializer.rb
index 501bb788e..1c1f7d0ad 100644
--- a/app/serializers/manifest_serializer.rb
+++ b/app/serializers/manifest_serializer.rb
@@ -39,7 +39,7 @@ class ManifestSerializer < ActiveModel::Serializer
   def icons
     ICON_SIZES.map do |size|
       {
-        src: full_pack_url("media/icons/android-chrome-#{size}x#{size}.png"),
+        src: frontend_asset_url("icons/android-chrome-#{size}x#{size}.png"),
         sizes: "#{size}x#{size}",
         type: 'image/png',
         purpose: 'any maskable',
diff --git a/app/serializers/rest/instance_serializer.rb b/app/serializers/rest/instance_serializer.rb
index d7ed381e1..fa926cd28 100644
--- a/app/serializers/rest/instance_serializer.rb
+++ b/app/serializers/rest/instance_serializer.rb
@@ -28,7 +28,7 @@ class REST::InstanceSerializer < ActiveModel::Serializer
       }
     else
       {
-        url: full_pack_url('media/images/preview.png'),
+        url: frontend_asset_url('images/preview.png'),
       }
     end
   end
diff --git a/app/serializers/rest/v1/instance_serializer.rb b/app/serializers/rest/v1/instance_serializer.rb
index 99d1b2bd6..fdf939cfc 100644
--- a/app/serializers/rest/v1/instance_serializer.rb
+++ b/app/serializers/rest/v1/instance_serializer.rb
@@ -33,7 +33,7 @@ class REST::V1::InstanceSerializer < ActiveModel::Serializer
   end
 
   def thumbnail
-    instance_presenter.thumbnail ? full_asset_url(instance_presenter.thumbnail.file.url(:'@1x')) : full_pack_url('media/images/preview.png')
+    instance_presenter.thumbnail ? full_asset_url(instance_presenter.thumbnail.file.url(:'@1x')) : frontend_asset_url('images/preview.png')
   end
 
   def stats
diff --git a/app/views/application/mailer/_checklist.html.haml b/app/views/application/mailer/_checklist.html.haml
index 9ee965593..83072bd36 100644
--- a/app/views/application/mailer/_checklist.html.haml
+++ b/app/views/application/mailer/_checklist.html.haml
@@ -11,9 +11,9 @@
                     %tr
                       %td.email-checklist-icons-checkbox-td
                         - if defined?(checked) && checked
-                          = image_tag full_pack_url('media/images/mailer-new/welcome/checkbox-on.png'), alt: '', width: 20, height: 20
+                          = image_tag frontend_asset_url('images/mailer-new/welcome/checkbox-on.png'), alt: '', width: 20, height: 20
                         - else
-                          = image_tag full_pack_url('media/images/mailer-new/welcome/checkbox-off.png'), alt: '', width: 20, height: 20
+                          = image_tag frontend_asset_url('images/mailer-new/welcome/checkbox-off.png'), alt: '', width: 20, height: 20
                       %td.email-checklist-icons-step-td
                         - if defined?(step_image_url)
                           = image_tag step_image_url, alt: '', width: 40, height: 40
diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml
index 6f6b1825f..c72107367 100755
--- a/app/views/layouts/application.html.haml
+++ b/app/views/layouts/application.html.haml
@@ -14,12 +14,12 @@
     %link{ rel: 'icon', href: '/favicon.ico', type: 'image/x-icon' }/
 
     - %w(16 32 48).each do |size|
-      %link{ rel: 'icon', sizes: "#{size}x#{size}", href: asset_pack_path("media/icons/favicon-#{size}x#{size}.png"), type: 'image/png' }/
+      %link{ rel: 'icon', sizes: "#{size}x#{size}", href: frontend_asset_path("icons/favicon-#{size}x#{size}.png"), type: 'image/png' }/
 
     - %w(57 60 72 76 114 120 144 152 167 180 1024).each do |size|
-      %link{ rel: 'apple-touch-icon', sizes: "#{size}x#{size}", href: asset_pack_path("media/icons/apple-touch-icon-#{size}x#{size}.png") }/
+      %link{ rel: 'apple-touch-icon', sizes: "#{size}x#{size}", href: frontend_asset_path("icons/apple-touch-icon-#{size}x#{size}.png") }/
 
-    %link{ rel: 'mask-icon', href: asset_pack_path('media/images/logo-symbol-icon.svg'), color: '#6364FF' }/
+    %link{ rel: 'mask-icon', href: frontend_asset_path('images/logo-symbol-icon.svg'), color: '#6364FF' }/
     %link{ rel: 'manifest', href: manifest_path(format: :json) }/
     %meta{ name: 'theme-color', content: '#191b22' }/
     %meta{ name: 'apple-mobile-web-app-capable', content: 'yes' }/
diff --git a/app/views/layouts/mailer.html.haml b/app/views/layouts/mailer.html.haml
index c0f9a0a55..270f2b1e0 100644
--- a/app/views/layouts/mailer.html.haml
+++ b/app/views/layouts/mailer.html.haml
@@ -50,7 +50,7 @@
                                 /[if mso]
                                   </v:textbox></v:rect>
                                 = link_to root_url, class: 'email-header-logo-a' do
-                                  = image_tag full_pack_url('media/images/mailer-new/common/logo-header.png'), alt: 'Mastodon', width: 157, height: 40
+                                  = image_tag frontend_asset_url('images/mailer-new/common/logo-header.png'), alt: 'Mastodon', width: 157, height: 40
 
                           -# Heading
                           = yield :heading
@@ -75,7 +75,7 @@
                   %td.email-footer-td
                     %p.email-footer-p
                       = link_to root_url, class: 'email-footer-logo-a' do
-                        = image_tag full_pack_url('media/images/mailer-new/common/logo-footer.png'), alt: 'Mastodon', width: 44, height: 44
+                        = image_tag frontend_asset_url('images/mailer-new/common/logo-footer.png'), alt: 'Mastodon', width: 44, height: 44
                     %p.email-footer-p
                       = t 'about.hosted_on', domain: site_hostname
                     %p.email-footer-p
diff --git a/app/views/notification_mailer/favourite.html.haml b/app/views/notification_mailer/favourite.html.haml
index 26bb31731..62c0a39ab 100644
--- a/app/views/notification_mailer/favourite.html.haml
+++ b/app/views/notification_mailer/favourite.html.haml
@@ -1,5 +1,5 @@
 = content_for :heading do
-  = render 'application/mailer/heading', heading_title: t('notification_mailer.favourite.title'), heading_subtitle: t('notification_mailer.favourite.body', name: @account.pretty_acct), heading_image_url: full_pack_url('media/images/mailer-new/heading/favorite.png')
+  = render 'application/mailer/heading', heading_title: t('notification_mailer.favourite.title'), heading_subtitle: t('notification_mailer.favourite.body', name: @account.pretty_acct), heading_image_url: frontend_asset_url('images/mailer-new/heading/favorite.png')
 %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
   %tr
     %td.email-body-padding-td
diff --git a/app/views/notification_mailer/follow.html.haml b/app/views/notification_mailer/follow.html.haml
index 2f7ba0a9c..607cdb366 100644
--- a/app/views/notification_mailer/follow.html.haml
+++ b/app/views/notification_mailer/follow.html.haml
@@ -1,5 +1,5 @@
 = content_for :heading do
-  = render 'application/mailer/heading', heading_title: t('notification_mailer.follow.title'), heading_subtitle: t('notification_mailer.follow.body', name: @account.pretty_acct), heading_image_url: full_pack_url('media/images/mailer-new/heading/user.png')
+  = render 'application/mailer/heading', heading_title: t('notification_mailer.follow.title'), heading_subtitle: t('notification_mailer.follow.body', name: @account.pretty_acct), heading_image_url: frontend_asset_url('images/mailer-new/heading/user.png')
 %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
   %tr
     %td.email-body-padding-td
diff --git a/app/views/notification_mailer/follow_request.html.haml b/app/views/notification_mailer/follow_request.html.haml
index 275d0c5b0..12e3e2ee3 100644
--- a/app/views/notification_mailer/follow_request.html.haml
+++ b/app/views/notification_mailer/follow_request.html.haml
@@ -1,5 +1,5 @@
 = content_for :heading do
-  = render 'application/mailer/heading', heading_title: t('notification_mailer.follow_request.title'), heading_subtitle: t('notification_mailer.follow_request.body', name: @account.pretty_acct), heading_image_url: full_pack_url('media/images/mailer-new/heading/follow.png')
+  = render 'application/mailer/heading', heading_title: t('notification_mailer.follow_request.title'), heading_subtitle: t('notification_mailer.follow_request.body', name: @account.pretty_acct), heading_image_url: frontend_asset_url('images/mailer-new/heading/follow.png')
 %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
   %tr
     %td.email-body-padding-td
diff --git a/app/views/notification_mailer/mention.html.haml b/app/views/notification_mailer/mention.html.haml
index 2420a42bf..83fa5086a 100644
--- a/app/views/notification_mailer/mention.html.haml
+++ b/app/views/notification_mailer/mention.html.haml
@@ -1,5 +1,5 @@
 = content_for :heading do
-  = render 'application/mailer/heading', heading_title: t('notification_mailer.mention.title'), heading_subtitle: t('notification_mailer.mention.body', name: @status.account.pretty_acct), heading_image_url: full_pack_url('media/images/mailer-new/heading/mention.png')
+  = render 'application/mailer/heading', heading_title: t('notification_mailer.mention.title'), heading_subtitle: t('notification_mailer.mention.body', name: @status.account.pretty_acct), heading_image_url: frontend_asset_url('images/mailer-new/heading/mention.png')
 %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
   %tr
     %td.email-body-padding-td
diff --git a/app/views/notification_mailer/reblog.html.haml b/app/views/notification_mailer/reblog.html.haml
index b32c98470..f91c678cf 100644
--- a/app/views/notification_mailer/reblog.html.haml
+++ b/app/views/notification_mailer/reblog.html.haml
@@ -1,5 +1,5 @@
 = content_for :heading do
-  = render 'application/mailer/heading', heading_title: t('notification_mailer.reblog.title'), heading_subtitle: t('notification_mailer.reblog.body', name: @account.pretty_acct), heading_image_url: full_pack_url('media/images/mailer-new/heading/boost.png')
+  = render 'application/mailer/heading', heading_title: t('notification_mailer.reblog.title'), heading_subtitle: t('notification_mailer.reblog.body', name: @account.pretty_acct), heading_image_url: frontend_asset_url('images/mailer-new/heading/boost.png')
 %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
   %tr
     %td.email-body-padding-td
diff --git a/app/views/shared/_og.html.haml b/app/views/shared/_og.html.haml
index 385351ee1..d1e3cd9c6 100644
--- a/app/views/shared/_og.html.haml
+++ b/app/views/shared/_og.html.haml
@@ -8,7 +8,7 @@
 = opengraph 'og:type', 'website'
 = opengraph 'og:title', instance_presenter.title
 = opengraph 'og:description', description
-= opengraph 'og:image', full_asset_url(thumbnail&.file&.url(:'@1x') || asset_pack_path('media/images/preview.png', protocol: :request))
+= opengraph 'og:image', full_asset_url(thumbnail&.file&.url(:'@1x') || frontend_asset_path('images/preview.png'))
 = opengraph 'og:image:width', thumbnail ? thumbnail.meta['width'] : '1200'
 = opengraph 'og:image:height', thumbnail ? thumbnail.meta['height'] : '630'
 = opengraph 'twitter:card', 'summary_large_image'
diff --git a/app/views/user_mailer/appeal_approved.html.haml b/app/views/user_mailer/appeal_approved.html.haml
index 2cf62de39..54e9a94a5 100644
--- a/app/views/user_mailer/appeal_approved.html.haml
+++ b/app/views/user_mailer/appeal_approved.html.haml
@@ -1,5 +1,5 @@
 = content_for :heading do
-  = render 'application/mailer/heading', heading_title: t('user_mailer.appeal_approved.title'), heading_subtitle: t('user_mailer.appeal_approved.subtitle'), heading_image_url: full_pack_url('media/images/mailer-new/heading/appeal-approved.png')
+  = render 'application/mailer/heading', heading_title: t('user_mailer.appeal_approved.title'), heading_subtitle: t('user_mailer.appeal_approved.subtitle'), heading_image_url: frontend_asset_url('images/mailer-new/heading/appeal-approved.png')
 %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
   %tr
     %td.email-body-padding-td
diff --git a/app/views/user_mailer/appeal_rejected.html.haml b/app/views/user_mailer/appeal_rejected.html.haml
index c24cf7647..b493712b0 100644
--- a/app/views/user_mailer/appeal_rejected.html.haml
+++ b/app/views/user_mailer/appeal_rejected.html.haml
@@ -1,5 +1,5 @@
 = content_for :heading do
-  = render 'application/mailer/heading', heading_title: t('user_mailer.appeal_rejected.title'), heading_subtitle: t('user_mailer.appeal_rejected.subtitle'), heading_image_url: full_pack_url('media/images/mailer-new/heading/appeal-rejected.png')
+  = render 'application/mailer/heading', heading_title: t('user_mailer.appeal_rejected.title'), heading_subtitle: t('user_mailer.appeal_rejected.subtitle'), heading_image_url: frontend_asset_url('images/mailer-new/heading/appeal-rejected.png')
 %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
   %tr
     %td.email-body-padding-td
diff --git a/app/views/user_mailer/backup_ready.html.haml b/app/views/user_mailer/backup_ready.html.haml
index 4a1e7b1c6..99a48e7fd 100644
--- a/app/views/user_mailer/backup_ready.html.haml
+++ b/app/views/user_mailer/backup_ready.html.haml
@@ -1,5 +1,5 @@
 = content_for :heading do
-  = render 'application/mailer/heading', heading_title: t('user_mailer.backup_ready.title'), heading_subtitle: t('user_mailer.backup_ready.explanation'), heading_image_url: full_pack_url('media/images/mailer-new/heading/archive.png')
+  = render 'application/mailer/heading', heading_title: t('user_mailer.backup_ready.title'), heading_subtitle: t('user_mailer.backup_ready.explanation'), heading_image_url: frontend_asset_url('images/mailer-new/heading/archive.png')
 %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
   %tr
     %td.email-body-padding-td
diff --git a/app/views/user_mailer/confirmation_instructions.html.haml b/app/views/user_mailer/confirmation_instructions.html.haml
index 4fd66d079..74b2d49a4 100644
--- a/app/views/user_mailer/confirmation_instructions.html.haml
+++ b/app/views/user_mailer/confirmation_instructions.html.haml
@@ -1,5 +1,5 @@
 = content_for :heading do
-  = render 'application/mailer/heading', heading_title: t('devise.mailer.confirmation_instructions.title'), heading_image_url: full_pack_url('media/images/mailer-new/heading/email.png')
+  = render 'application/mailer/heading', heading_title: t('devise.mailer.confirmation_instructions.title'), heading_image_url: frontend_asset_url('images/mailer-new/heading/email.png')
 %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
   %tr
     %td.email-body-padding-td
diff --git a/app/views/user_mailer/email_changed.html.haml b/app/views/user_mailer/email_changed.html.haml
index 741c2bde1..71678ad02 100644
--- a/app/views/user_mailer/email_changed.html.haml
+++ b/app/views/user_mailer/email_changed.html.haml
@@ -1,5 +1,5 @@
 = content_for :heading do
-  = render 'application/mailer/heading', heading_title: t('devise.mailer.email_changed.title'), heading_subtitle: t('devise.mailer.email_changed.explanation'), heading_image_url: full_pack_url('media/images/mailer-new/heading/email.png')
+  = render 'application/mailer/heading', heading_title: t('devise.mailer.email_changed.title'), heading_subtitle: t('devise.mailer.email_changed.explanation'), heading_image_url: frontend_asset_url('images/mailer-new/heading/email.png')
 %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
   %tr
     %td.email-body-padding-td
diff --git a/app/views/user_mailer/password_change.html.haml b/app/views/user_mailer/password_change.html.haml
index 08b4ecbbd..44c8c0dca 100644
--- a/app/views/user_mailer/password_change.html.haml
+++ b/app/views/user_mailer/password_change.html.haml
@@ -1,5 +1,5 @@
 = content_for :heading do
-  = render 'application/mailer/heading', heading_title: t('devise.mailer.password_change.title'), heading_subtitle: t('devise.mailer.password_change.explanation'), heading_image_url: full_pack_url('media/images/mailer-new/heading/password.png')
+  = render 'application/mailer/heading', heading_title: t('devise.mailer.password_change.title'), heading_subtitle: t('devise.mailer.password_change.explanation'), heading_image_url: frontend_asset_url('images/mailer-new/heading/password.png')
 %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
   %tr
     %td.email-body-padding-td
diff --git a/app/views/user_mailer/reconfirmation_instructions.html.haml b/app/views/user_mailer/reconfirmation_instructions.html.haml
index 8aa223015..854887a7e 100644
--- a/app/views/user_mailer/reconfirmation_instructions.html.haml
+++ b/app/views/user_mailer/reconfirmation_instructions.html.haml
@@ -1,5 +1,5 @@
 = content_for :heading do
-  = render 'application/mailer/heading', heading_title: t('devise.mailer.reconfirmation_instructions.title'), heading_image_url: full_pack_url('media/images/mailer-new/heading/email.png')
+  = render 'application/mailer/heading', heading_title: t('devise.mailer.reconfirmation_instructions.title'), heading_image_url: frontend_asset_url('images/mailer-new/heading/email.png')
 %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
   %tr
     %td.email-body-padding-td
diff --git a/app/views/user_mailer/reset_password_instructions.html.haml b/app/views/user_mailer/reset_password_instructions.html.haml
index 0db79daaf..a1384fcc2 100644
--- a/app/views/user_mailer/reset_password_instructions.html.haml
+++ b/app/views/user_mailer/reset_password_instructions.html.haml
@@ -1,5 +1,5 @@
 = content_for :heading do
-  = render 'application/mailer/heading', heading_title: t('devise.mailer.reset_password_instructions.title'), heading_subtitle: t('devise.mailer.reset_password_instructions.explanation'), heading_image_url: full_pack_url('media/images/mailer-new/heading/password.png')
+  = render 'application/mailer/heading', heading_title: t('devise.mailer.reset_password_instructions.title'), heading_subtitle: t('devise.mailer.reset_password_instructions.explanation'), heading_image_url: frontend_asset_url('images/mailer-new/heading/password.png')
 %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
   %tr
     %td.email-body-padding-td
diff --git a/app/views/user_mailer/suspicious_sign_in.html.haml b/app/views/user_mailer/suspicious_sign_in.html.haml
index e2cb916bf..deee7a1ce 100644
--- a/app/views/user_mailer/suspicious_sign_in.html.haml
+++ b/app/views/user_mailer/suspicious_sign_in.html.haml
@@ -1,5 +1,5 @@
 = content_for :heading do
-  = render 'application/mailer/heading', heading_title: t('user_mailer.suspicious_sign_in.title'), heading_subtitle: t('user_mailer.suspicious_sign_in.explanation'), heading_image_url: full_pack_url('media/images/mailer-new/heading/login.png')
+  = render 'application/mailer/heading', heading_title: t('user_mailer.suspicious_sign_in.title'), heading_subtitle: t('user_mailer.suspicious_sign_in.explanation'), heading_image_url: frontend_asset_url('images/mailer-new/heading/login.png')
 %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
   %tr
     %td.email-body-padding-td
diff --git a/app/views/user_mailer/two_factor_disabled.html.haml b/app/views/user_mailer/two_factor_disabled.html.haml
index 0d8ff5c69..28f6ca660 100644
--- a/app/views/user_mailer/two_factor_disabled.html.haml
+++ b/app/views/user_mailer/two_factor_disabled.html.haml
@@ -1,5 +1,5 @@
 = content_for :heading do
-  = render 'application/mailer/heading', heading_title: t('devise.mailer.two_factor_disabled.title'), heading_subtitle: t('devise.mailer.two_factor_disabled.subtitle'), heading_image_url: full_pack_url('media/images/mailer-new/heading/2fa-disabled.png')
+  = render 'application/mailer/heading', heading_title: t('devise.mailer.two_factor_disabled.title'), heading_subtitle: t('devise.mailer.two_factor_disabled.subtitle'), heading_image_url: frontend_asset_url('images/mailer-new/heading/2fa-disabled.png')
 %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
   %tr
     %td.email-body-padding-td
diff --git a/app/views/user_mailer/two_factor_enabled.html.haml b/app/views/user_mailer/two_factor_enabled.html.haml
index 6fe03eab2..691dc661a 100644
--- a/app/views/user_mailer/two_factor_enabled.html.haml
+++ b/app/views/user_mailer/two_factor_enabled.html.haml
@@ -1,5 +1,5 @@
 = content_for :heading do
-  = render 'application/mailer/heading', heading_title: t('devise.mailer.two_factor_enabled.title'), heading_subtitle: t('devise.mailer.two_factor_enabled.subtitle'), heading_image_url: full_pack_url('media/images/mailer-new/heading/2fa-enabled.png')
+  = render 'application/mailer/heading', heading_title: t('devise.mailer.two_factor_enabled.title'), heading_subtitle: t('devise.mailer.two_factor_enabled.subtitle'), heading_image_url: frontend_asset_url('images/mailer-new/heading/2fa-enabled.png')
 %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
   %tr
     %td.email-body-padding-td
diff --git a/app/views/user_mailer/two_factor_recovery_codes_changed.html.haml b/app/views/user_mailer/two_factor_recovery_codes_changed.html.haml
index dff0620ce..2d063e4c7 100644
--- a/app/views/user_mailer/two_factor_recovery_codes_changed.html.haml
+++ b/app/views/user_mailer/two_factor_recovery_codes_changed.html.haml
@@ -1,5 +1,5 @@
 = content_for :heading do
-  = render 'application/mailer/heading', heading_title: t('devise.mailer.two_factor_recovery_codes_changed.title'), heading_subtitle: t('devise.mailer.two_factor_recovery_codes_changed.subtitle'), heading_image_url: full_pack_url('media/images/mailer-new/heading/2fa-recovery.png')
+  = render 'application/mailer/heading', heading_title: t('devise.mailer.two_factor_recovery_codes_changed.title'), heading_subtitle: t('devise.mailer.two_factor_recovery_codes_changed.subtitle'), heading_image_url: frontend_asset_url('images/mailer-new/heading/2fa-recovery.png')
 %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
   %tr
     %td.email-body-padding-td
diff --git a/app/views/user_mailer/warning.html.haml b/app/views/user_mailer/warning.html.haml
index 4dfbfc231..837cde550 100644
--- a/app/views/user_mailer/warning.html.haml
+++ b/app/views/user_mailer/warning.html.haml
@@ -1,5 +1,5 @@
 = content_for :heading do
-  = render 'application/mailer/heading', heading_title: t("user_mailer.warning.title.#{@warning.action}"), heading_image_url: full_pack_url('media/images/mailer-new/heading/warning.png')
+  = render 'application/mailer/heading', heading_title: t("user_mailer.warning.title.#{@warning.action}"), heading_image_url: frontend_asset_url('images/mailer-new/heading/warning.png')
 %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
   %tr
     %td.email-body-padding-td
diff --git a/app/views/user_mailer/webauthn_credential_added.html.haml b/app/views/user_mailer/webauthn_credential_added.html.haml
index 334eb3e32..3e1676623 100644
--- a/app/views/user_mailer/webauthn_credential_added.html.haml
+++ b/app/views/user_mailer/webauthn_credential_added.html.haml
@@ -1,5 +1,5 @@
 = content_for :heading do
-  = render 'application/mailer/heading', heading_title: t('devise.mailer.webauthn_credential.added.title'), heading_subtitle: t('devise.mailer.webauthn_credential.added.explanation'), heading_image_url: full_pack_url('media/images/mailer-new/heading/key-added.png')
+  = render 'application/mailer/heading', heading_title: t('devise.mailer.webauthn_credential.added.title'), heading_subtitle: t('devise.mailer.webauthn_credential.added.explanation'), heading_image_url: frontend_asset_url('images/mailer-new/heading/key-added.png')
 %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
   %tr
     %td.email-body-padding-td
diff --git a/app/views/user_mailer/webauthn_credential_deleted.html.haml b/app/views/user_mailer/webauthn_credential_deleted.html.haml
index 5fad523b4..59dcb75d3 100644
--- a/app/views/user_mailer/webauthn_credential_deleted.html.haml
+++ b/app/views/user_mailer/webauthn_credential_deleted.html.haml
@@ -1,5 +1,5 @@
 = content_for :heading do
-  = render 'application/mailer/heading', heading_title: t('devise.mailer.webauthn_credential.deleted.title'), heading_subtitle: t('devise.mailer.webauthn_credential.deleted.explanation'), heading_image_url: full_pack_url('media/images/mailer-new/heading/key-deleted.png')
+  = render 'application/mailer/heading', heading_title: t('devise.mailer.webauthn_credential.deleted.title'), heading_subtitle: t('devise.mailer.webauthn_credential.deleted.explanation'), heading_image_url: frontend_asset_url('images/mailer-new/heading/key-deleted.png')
 %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
   %tr
     %td.email-body-padding-td
diff --git a/app/views/user_mailer/webauthn_disabled.html.haml b/app/views/user_mailer/webauthn_disabled.html.haml
index 017412536..0f7c534bc 100644
--- a/app/views/user_mailer/webauthn_disabled.html.haml
+++ b/app/views/user_mailer/webauthn_disabled.html.haml
@@ -1,5 +1,5 @@
 = content_for :heading do
-  = render 'application/mailer/heading', heading_title: t('devise.mailer.webauthn_disabled.title'), heading_subtitle: t('devise.mailer.webauthn_disabled.explanation'), heading_image_url: full_pack_url('media/images/mailer-new/heading/key-disabled.png')
+  = render 'application/mailer/heading', heading_title: t('devise.mailer.webauthn_disabled.title'), heading_subtitle: t('devise.mailer.webauthn_disabled.explanation'), heading_image_url: frontend_asset_url('images/mailer-new/heading/key-disabled.png')
 %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
   %tr
     %td.email-body-padding-td
diff --git a/app/views/user_mailer/webauthn_enabled.html.haml b/app/views/user_mailer/webauthn_enabled.html.haml
index 3257d14df..cd11aa5a4 100644
--- a/app/views/user_mailer/webauthn_enabled.html.haml
+++ b/app/views/user_mailer/webauthn_enabled.html.haml
@@ -1,5 +1,5 @@
 = content_for :heading do
-  = render 'application/mailer/heading', heading_title: t('devise.mailer.webauthn_enabled.title'), heading_subtitle: t('devise.mailer.webauthn_enabled.explanation'), heading_image_url: full_pack_url('media/images/mailer-new/heading/key-enabled.png')
+  = render 'application/mailer/heading', heading_title: t('devise.mailer.webauthn_enabled.title'), heading_subtitle: t('devise.mailer.webauthn_enabled.explanation'), heading_image_url: frontend_asset_url('images/mailer-new/heading/key-enabled.png')
 %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
   %tr
     %td.email-body-padding-td