Logo
Home
Resources

Product

Custom Workflow

Resources

Blog
Youtube
Template
Home
>
Product
>
Template Top
>
detail

HubSpot CMS: Implementing a High-Converting "Rich CTA" Module with Shine Effects

n conversion-focused web design, a simple "Submit" button or text link often fails to capture user interest. especially for high-value offers like Whitepapers or Webinars. To increase conversions, you need a button that communicates value visually through a Thumbnail Image and Microcopy (Supplemental Text).

This article introduces a high-performance CTA module that grabs attention with an automatic "Shine" animation and engages users with a smooth hover effect.

‍

Demo Video

Over view
Code

Detail

Purpose and Benefits

The primary goal of this module is to capture user attention and reduce the psychological barrier to clicking.

Key Benefits:

  • Attention-Grabbing: A "Shine" animation runs across the button every 4 seconds, naturally drawing the eye to the conversion point.
  • Information Density: You can include a thumbnail image, top text (microcopy), and main text. This tells the user exactly what they are getting (e.g., a PDF cover) before they click.
  • Hybrid Operation: You can switch between "HubSpot CTA Mode" (for tracking views/clicks via HubSpot tools) and "Custom Mode" (for full design freedom within the page editor).
  • No-Code Styling: Colors for the default state, hover state, and borders can be customized directly in the editor to match your brand.

Use Cases

This design is ideal for high-priority actions where you want to stand out:

  • Whitepaper/E-book Downloads
    • Thumbnail: PDF Cover Image
    • Top Text: "Free Guide"
    • Main Text: "Download the 2024 Report"
  • Webinar Registration
    • Thumbnail: Speaker's Photo
    • Top Text: "Live on Oct 10th"
    • Main Text: "Reserve Your Seat"
  • Product Demos
    • Thumbnail: Product Logo
    • Top Text: "30-Day Free Trial"
    • Main Text: "Get Started Now"

How to Use in HubSpot CMS

Once implemented in the Design Manager, here is how to use it in the Page Editor:

1. Select Button Type

First, choose how you want to manage the button:

  • Custom (Use module fields): Recommended. You set the image, text, and link directly in this module.
  • HubSpot CTA (Select existing): Select a CTA created in HubSpot's Marketing > Lead Capture > CTAs tool.
    • Note: Even if you select a native HubSpot CTA, the "Shine" and "Hover" CSS effects defined in this module will still apply to it.

2. Configure Content (If "Custom" is selected)

If you chose "Custom", the following fields will appear:

  • Link: Set the destination URL (External, Content, File, Email, etc.).
  • Thumbnail Image: Select the image to appear on the left side (e.g., document cover).
  • Top Text: Small text above the main label (e.g., "Limited Time").
  • Main Text: The primary button label.

3. Adjust Styles

In the "Styles" group, you can customize the look without coding:

  • Colors: Set Base and Hover colors for both the background and text.
  • Border: Adjust the border color and thickness.
  • Text Size: Independently adjust the font size for the Top Text and Main Text.

Module Source Code

Create a new module in the HubSpot Design Manager and paste the following code into the respective files.

1. fields.json

This file uses the visibility property to show/hide fields based on the "Button Type" selection, keeping the editor clean.

[
 {
  "choices": [
   [
    "custom",
    "Custom (Use module fields)"
   ],
   [
    "cta",
    "HubSpot CTA (Select existing)"
   ]
  ],
  "display": "select",
  "display_width": null,
  "id": "86abe95d-12cc-4468-0761-41f0be18f1d6",
  "label": "Button Type",
  "locked": false,
  "multiple": false,
  "name": "button_type",
  "preset": null,
  "reordering_enabled": true,
  "required": false,
  "type": "choice"
 },
 {
  "display_width": null,
  "id": "de5d23b2-d299-d748-e214-c43db3a1526b",
  "label": "Select CTA",
  "locked": false,
  "name": "cta_field",
  "required": false,
  "type": "cta",
  "visibility": {
   "controlling_field_path": "button_type",
   "controlling_value_regex": "cta",
   "operator": "EQUAL"
  }
 },
 {
  "default": {
   "url": {
    "content_id": null,
    "type": "EXTERNAL",
    "href": ""
   },
   "open_in_new_tab": false,
   "no_follow": false
  },
  "display_width": null,
  "id": "4ed2abf9-80f9-3a59-7029-e2ff4b992b2f",
  "label": "Link",
  "locked": false,
  "name": "link_field",
  "required": false,
  "show_advanced_rel_options": false,
  "supported_types": [
   "EXTERNAL",
   "CONTENT",
   "FILE",
   "EMAIL_ADDRESS",
   "BLOG",
   "CALL_TO_ACTION",
   "PHONE_NUMBER",
   "WHATSAPP_NUMBER",
   "PAYMENT"
  ],
  "type": "link",
  "visibility": {
   "controlling_field_path": "button_type",
   "controlling_value_regex": "custom",
   "operator": "EQUAL"
  }
 },
 {
  "default": {
   "size_type": "auto",
   "src": "",
   "alt": null,
   "loading": "lazy"
  },
  "display_width": null,
  "id": "5fb752e9-691e-7b11-a612-94cac8189962",
  "label": "Thumbnail Image",
  "locked": false,
  "name": "thumbnail",
  "required": false,
  "resizable": true,
  "responsive": true,
  "show_loading": false,
  "type": "image",
  "visibility": {
   "controlling_field_path": "button_type",
   "controlling_value_regex": "custom",
   "operator": "EQUAL"
  }
 },
 {
  "allow_new_line": false,
  "display_width": null,
  "id": "0726cb7f-8436-4243-dcec-36ba8bcfb6b1",
  "label": "Top Text (Microcopy)",
  "locked": false,
  "name": "top_text",
  "required": false,
  "type": "text",
  "visibility": {
   "controlling_field_path": "button_type",
   "controlling_value_regex": "custom",
   "operator": "EQUAL"
  }
 },
 {
  "allow_new_line": false,
  "display_width": null,
  "id": "85113087-5591-64c7-c052-2d9720c1ab49",
  "label": "Main Button Text",
  "locked": false,
  "name": "main_text",
  "required": false,
  "type": "text",
  "visibility": {
   "controlling_field_path": "button_type",
   "controlling_value_regex": "custom",
   "operator": "EQUAL"
  }
 },
 {
  "children": [
   {
    "default": {
     "color": null,
     "opacity": null
    },
    "display_width": null,
    "id": "a757c310-1dc8-9f7f-5f73-20dc89173b3e",
    "label": "Base Background Color",
    "locked": false,
    "name": "base_bg_color",
    "required": false,
    "type": "color"
   },
   {
    "default": {
     "color": null,
     "opacity": null
    },
    "display_width": null,
    "id": "44209241-2b72-bb28-b166-ef57a7222a8e",
    "label": "Hover Background Color",
    "locked": false,
    "name": "hover_bg_color",
    "required": false,
    "type": "color"
   },
   {
    "default": {
     "color": null,
     "opacity": null
    },
    "display_width": null,
    "id": "d4f266ca-e938-b1b0-1d3d-4c0a027fe887",
    "label": "Base Text Color",
    "locked": false,
    "name": "base_text_color",
    "required": false,
    "type": "color"
   },
   {
    "default": {
     "color": null,
     "opacity": null
    },
    "display_width": null,
    "id": "64278894-20a7-cf1e-52c9-966217d6d4fb",
    "label": "Hover Text Color",
    "locked": false,
    "name": "hover_text_color",
    "required": false,
    "type": "color"
   },
   {
    "default": {
     "color": null,
     "opacity": null
    },
    "display_width": null,
    "id": "5c01e696-9336-1fcf-e5e4-1987e32d44f4",
    "label": "Border Color",
    "locked": false,
    "name": "border_color",
    "required": false,
    "type": "color"
   },
   {
    "display": "text",
    "display_width": null,
    "id": "a3f5c61a-7ed6-4e17-386b-5550214aca9d",
    "label": "Border Size (px)",
    "locked": false,
    "name": "border_size",
    "required": false,
    "step": 1,
    "type": "number"
   },
   {
    "display": "text",
    "display_width": null,
    "id": "6fb4ebf9-4b2d-c15b-0177-0a8594cacbd1",
    "label": "Top Text Size (px)",
    "locked": false,
    "name": "top_text_size",
    "required": false,
    "step": 1,
    "type": "number"
   },
   {
    "display": "text",
    "display_width": null,
    "id": "81d85724-0b11-31dd-c5e6-937e2270b8c3",
    "label": "Main Text Size (px)",
    "locked": false,
    "name": "main_text_size",
    "required": false,
    "step": 1,
    "type": "number"
   }
  ],
  "default": {
   "base_bg_color": {
    "color": null,
    "opacity": null
   },
   "hover_bg_color": {
    "color": null,
    "opacity": null
   },
   "base_text_color": {
    "color": null,
    "opacity": null
   },
   "hover_text_color": {
    "color": null,
    "opacity": null
   },
   "border_color": {
    "color": null,
    "opacity": null
   }
  },
  "display_width": null,
  "expanded": false,
  "group_occurrence_meta": null,
  "id": "cf5f24f0-39f9-9be6-2158-e2fb915743ad",
  "label": "Styles",
  "locked": false,
  "name": "styles",
  "required": false,
  "tab": "CONTENT",
  "type": "group"
 }
]

‍

Source Code

HTML
<div id="anime-cta-{{ module.id }}" class="anime-cta-wrapper">

  {# --- Pattern A: Use HubSpot CTA --- #}
  {% if module.button_type == 'cta' %}
  
    {# Inject classes into the CTA macro to apply designs #}
    {% cta guid="{{ module.cta_field }}" extra_classes="anime-cta-button cta-mode" %}
    
  {# --- Pattern B: Use Custom Design --- #}
  {% else %}
  
    {% set href = module.link_field.url.href %}
    {% if module.link_field.url.type is equalto "EMAIL_ADDRESS" %}
      {% set href = "mailto:" + href %}
    {% endif %}
    
    <a href="{{ href }}" 
       class="anime-cta-button custom-mode"
       {% if module.link_field.open_in_new_tab %}target="_blank"{% endif %}
       {% if module.link_field.no_follow %}rel="nofollow"{% endif %}>
       
       {# Image #}
       {% if module.thumbnail.src %}
         <div class="anime-cta-button__img-wrapper">
           <img src="{{ module.thumbnail.src }}" alt="{{ module.thumbnail.alt }}" width="{{ module.thumbnail.width }}" height="{{ module.thumbnail.height }}">
         </div>
       {% endif %}

       {# Text Content #}
       <div class="anime-cta-button__content">
         {% if module.top_text %}
           <p class="anime-cta-button__subtext">{{ module.top_text }}</p>
         {% endif %}
         {% if module.main_text %}
           <span class="anime-cta-button__maintext">{{ module.main_text }}</span>
         {% endif %}
       </div>

       {# CSS Arrow #}
       <span class="anime-cta-button__arrow"></span>
       
       {# Shine Effect Span #}
       <span class="anime-cta-button__shine"></span>
    </a>
    
  {% endif %}

</div>

{% require_css %}
<style>
  #anime-cta-{{ module.id }} {
    --base-bg: {{ module.styles.base_bg_color.css || '#fff' }};
    --hover-bg: {{ module.styles.hover_bg_color.css || '#003386' }};
    --base-text: {{ module.styles.base_text_color.css || '#003386' }};
    --hover-text: {{ module.styles.hover_text_color.css || '#fff' }};
    --border-color: {{ module.styles.border_color.css || '#fff' }};
    --border-size: {{ module.styles.border_size || 1 }}px;
    --sub-font-size: {{ module.styles.top_text_size || 14 }}px;
    --main-font-size: {{ module.styles.main_text_size || 18 }}px;
  }
</style>
{% end_require_css %}

‍

CSS
/* Container */
.anime-cta-wrapper {
  width: 100%;
  max-width: 500px;
  margin: 0 auto;
  font-family: sans-serif;
}

/* Common Button Styles (Applies to both Custom <a> and HubSpot CTA) */
.anime-cta-button,
.anime-cta-wrapper .cta_button {
  position: relative;
  display: flex !important; /* Overwrite CTA default styles */
  align-items: center;
  justify-content: center;
  gap: 1rem;
  padding: 1rem 1.5rem;
  width: 100%;
  box-sizing: border-box;
  
  background-color: var(--base-bg);
  border: var(--border-size) solid var(--border-color);
  border-radius: 8px;
  text-decoration: none;
  color: var(--base-text);
  
  overflow: hidden;
  box-shadow: 0 4px 6px rgba(0,0,0,0.1);
  transition: color 0.3s ease, border-color 0.3s ease;
  z-index: 1;
  
  /* Font settings */
  font-weight: bold;
  line-height: 1.4;
}

/* Hover Background Slide (Pseudo-element) */
.anime-cta-button::before,
.anime-cta-wrapper .cta_button::before {
  content: '';
  position: absolute;
  top: 0;
  left: -130%;
  width: 140%;
  height: 100%;
  background-color: var(--hover-bg);
  transform: skewX(-25deg);
  transition: left 0.4s cubic-bezier(0.4, 0, 0.2, 1);
  z-index: -1;
}

/* Hover Behavior */
.anime-cta-button:hover,
.anime-cta-wrapper .cta_button:hover {
  color: var(--hover-text);
  border-color: var(--hover-bg);
}

.anime-cta-button:hover::before,
.anime-cta-wrapper .cta_button:hover::before {
  left: -20%;
}

/* --- Internal Content (For Custom Mode) --- */
.anime-cta-button__img-wrapper {
  flex-shrink: 0;
  width: 100px;
  z-index: 2;
  display: flex; /* Adjust image vertical alignment */
  align-items: center;
}
.anime-cta-button__img-wrapper img {
  display: block;
  width: 100%;
  height: auto;
  object-fit: contain; /* Maintain ratio */
}

.anime-cta-button__content {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  z-index: 2;
  line-height: 1.2;
}

.anime-cta-button__subtext {
  font-size: var(--sub-font-size);
  margin: 0 0 4px 0;
  display: block;
}

.anime-cta-button__maintext {
  font-size: var(--main-font-size);
}

.anime-cta-button__arrow {
  display: block;
  width: 10px;
  height: 10px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(-45deg);
  margin-right: 5px;
  transition: border-color 0.3s;
  z-index: 2;
}

/* --- Shine Animation --- */
/* For Custom Mode */
.anime-cta-button__shine {
  position: absolute;
  top: 0;
  left: -150%;
  width: 50%;
  height: 100%;
  background: linear-gradient(to right, rgba(255,255,255,0) 0%, rgba(255,255,255,0.6) 50%, rgba(255,255,255,0) 100%);
  transform: skewX(-25deg);
  z-index: 0;
  pointer-events: none;
  animation: shine-effect 4s infinite linear;
}

/* For CTA Mode (Using After pseudo-element) */
.cta-mode::after {
  content: '';
  position: absolute;
  top: 0;
  left: -150%;
  width: 50%;
  height: 100%;
  background: linear-gradient(to right, rgba(255,255,255,0) 0%, rgba(255,255,255,0.6) 50%, rgba(255,255,255,0) 100%);
  transform: skewX(-25deg);
  z-index: 0;
  pointer-events: none;
  animation: shine-effect 4s infinite linear;
}

@keyframes shine-effect {
  0% { left: -150%; opacity: 0; }
  10% { opacity: 1; }
  20% { left: 150%; opacity: 0; }
  100% { left: 150%; opacity: 0; }
}

/* Mobile Responsiveness */
@media (max-width: 600px) {
  .anime-cta-button, 
  .anime-cta-wrapper .cta_button {
    padding: 1rem;
    gap: 0.5rem;
  }
  .anime-cta-button__img-wrapper {
    width: 60px;
  }
}
Javascript

FAQ

Which mode should I choose: "Custom" or "HubSpot CTA"?

We recommend "Custom" if you prioritize design fidelity, and "HubSpot CTA" if you prioritize tracking features. Custom: This allows you to easily reproduce the module's signature layout (Thumbnail Image + Microcopy + Main Text) simply by filling in the fields. It is ideal when you want to strongly emphasize visual information, such as for a whitepaper download or event registration. HubSpot CTA: This calls a button created with HubSpot's standard "CTA tool." This is useful if you want to utilize features like A/B Testing or Smart Content. However, please note that the layout of images and text will depend on your settings within the standard CTA tool, so the full "rich layout" of this module may not be perfectly replicated (though the shimmering effect and color styles will still apply).

Can I change the animation interval (currently 4 seconds) or speed?

Yes, but adjusting the timing requires editing the CSS (stylesheet). While colors and font sizes can be freely changed via the page editor (no-code), the timing of the "shine" animation is defined within the code. To change it, navigate to the CSS section of the module and adjust the value in the following line: CSS /* Change '4s' to your preferred duration (e.g., '2s' or '6s') */ animation: shine-effect 4s infinite linear; Decreasing the number makes the shine appear more frequently, while increasing it creates a longer pause between effects.

Is this module mobile-responsive? Are there recommended image dimensions?

Yes, it is fully responsive. Square or slightly landscape images work best. On smartphones (screens 600px wide or less), the module automatically adjusts the padding and image size to maintain readability and layout balance. Regarding the thumbnail image, the CSS uses object-fit: contain to ensure the image fits within the frame without distortion. However, for the most aesthetically pleasing balance with the text, we recommend using images with a Square (1:1) or slightly Landscape (4:3) aspect ratio.

Search

Search more

Related Template

Need Customization?

We can customize this sample to match your specific business requirements.

Book Free Consultation

Got a quick dev request?

Put it on Trello!Need a fix for HubSpot, CMS, or GAS? Post it on Trello.

Development Requests Here

How to Configure Date Add/Subtract Actions in HubSpot Custom Workflows

HubSpot CMS: Implementing a High-Converting "Rich CTA" Module with Shine Effects

HubSpot CMS: A Responsive "Definition List" Module for Event Overviews & Specs

HubSpot CMS: Implementing a "Step Flow" Module for Process Visualization

GAS Library: Automated Blog Post NG Word Checking with AI (Gemini/OpenAI)

Company Info
Name : SweetsVillage .Inc
CEO :
‍
Tomoo Motoyama

HomeTemplateCustomWorkflow
Terms & ConditionsPrivacy PolicyContact us

Copyright ©SweetsVillage .Inc

Back To Top Image