📘 HubSpot CMS Development Textbook — 2026 Edition
Chapter 10 — Final Chapter

Maintenance, operation, and handover design

Delivery is the start, not the goal. In this chapter, we will systematically explain everything from designing a maintenance system, creating handover documents, coding rules for operation, and responding to HubSpot updates, so that our clients can operate their sites stably over the long term.

🎯 Target level:All levels (required reading)
⏱ Estimated reading completion:60 minutes
🔗 Previous chapter:Chapter 9 Development Environment/CLI/Deployment Workflow

Contents of this chapter

  1. Design a maintenance system after delivery
  2. Handover document design to client
  3. Module/template design with operation in mind
  4. Coding and commenting conventions
  5. Responding to HubSpot updates and regular maintenance
  6. Common operational problems and solutions
  7. Regular performance monitoring
  8. Long-term operation checklist
  9. Textbook Summary: As a HubSpot CMS Developer
Section 10-1

Design a maintenance system after delivery

Many projects enter the operational phase with the understanding that ``it's over once it's delivered.'' Confusion will ensue later.The maintenance system will be designed and agreed with the client before delivery.It's a thing.

Clarify the division of roles in the maintenance phase

There are two axes to running a HubSpot site: technical maintenance and content operations. First, organize who will be responsible for what.

⚙️ Engineer

  • Template module modification
  • Development of new modules
  • Deployment via CLI
  • Performance improvement
  • HubSpot update compatible
  • Security confirmation

📣 Marketer

  • Creating and editing blog articles and pages
  • Setting/changing CTA
  • Creating/editing forms
  • Manage HubDB records
  • Workflow settings
  • Report confirmation

🔑 Client responsible

  • Content approval/publication decision
  • Maintenance request window
  • HubSpot plan management
  • User privilege management
  • Billing/contract management

Maintenance contract types and content definitions

Contract typeMain contentsEstimated man-hours/month
spot maintenance Request based. We provide estimates for any repairs or additional development that occur. Each case
light maintenance Monthly performance check and minor corrections (about 1-2 hours/month) 2~4h/month
standard maintenance Including minor repairs, one new module development, and monthly report submission. 8~16h/month
full maintenance Including content update agency, SEO measures, A/B testing, additional function development 20h~/month

Maintenance request flow design

1

Request reception (Slack / email / ticket)

Unify the counter into one. For ambiguous requests such as "I want to modify the design," we will conduct a hearing to find out the specific requirements. Create a rule that requires screenshots and URLs to be attached.

2

Confirm the affected range and estimate man-hours

Verify that your changes do not affect other page modules. We will determine whether we can handle the work based on the contracted man-hours, and if it exceeds the contract, we will provide an additional estimate.

3

Request implementation/confirmation on the development portal

Don't touch the actual production directly, be sure to implement it on the development portal and then share the confirmation URL with the client.

4

client approval

As a general rule, approval should be obtained in writing (email/Slack) rather than orally. Just saying "No problem" is OK.

5

Production deployment/confirmation/reporting

Type git tag and check the target page after production deployment. Report work completed to client and close ticket.


Section 10-2

Handover document design to client

The handover document isEnabling marketers and content managers to run on their ownIt's for. If you write it from an engineer's perspective, the document will be too difficult. It is important to design your content to suit the audience.

Structure of transfer document

📄 Table of Contents of handover document for clients

① Site overview/basic information

  • HubSpot portal ID and login URL
  • Production URL/Staging URL
  • Your plan and included features
  • How to check contract renewal date and billing information
  • Technical contact information (engineer)

② Daily operation guide

  • Steps to create and publish a new blog article
  • Steps to edit text and images on existing pages
  • Steps to add/edit records to HubDB
  • Steps to change form content
  • Steps to upload images to file manager

③ How to use custom modules

  • Module list and usage explanation of each module
  • Field setting guide for frequently used modules
  • Recommended image size and file format
  • Clarification of "things not to do" (operations that break)

④ Tag/URL design rules

  • Blog tag naming convention (type: / cat: / status:)
  • URL slug naming rules (alphanumeric characters/hyphens)
  • Guide to writing page titles and meta descriptions

⑤ Frequently asked questions (FAQ)

  • What to do if the image is not displayed
  • What to do if the page gets 404
  • Where to check if the form is not submitted
  • How to contact maintenance requests and estimated response time

Module-specific operation guide template

If you have many modules, writing them all in one document will make it difficult to read. 1 page per moduleIn the style of The most commonly used format is to organize it in Notion or an internal wiki.

Module operation guide page structure template (for Notion, etc.)
# Hero Banner Module Operation Guide

## What is this module?
A banner that displays a large image and catchphrase at the top of the page.
It is placed on the top page, service page, etc.

## Field description

| Field name | Contents | Notes |
|-------------|------|---------|
| Heading | Banner main text | Maximum 30 characters recommended |
| Subheading | Supplementary text below the heading | Optional |
| Background image | Background image for the entire banner | Recommended size: 1440x640px |
| CTA button text | Text to display on the button | Recommended maximum of 15 characters |
| CTA button link | Button link URL | External link opens in a separate tab |

## Recommended image size
- Width: 1440px or more
- Height: 640px ~ 800px
- File format: JPG (photo) / PNG (with transparency)
- File size: Recommended to compress to 2MB or less

## Things not to do
⚠️ Do not use vertical images (ratio less than 1:1).
   The layout may be distorted when displayed on a PC.
⚠️ When you use an image with text as a background,
   It may not be readable on mobile.
💡 Video manuals are the most effective

Along with text documents,Record the operation video with Loom or screen recorder and send itand The client's self-propelled rate will increase dramatically. With just one “5 minute video of creating a new blog article and publishing it,” You won't get asked the same questions over and over again. It is especially effective to explain how to operate HubDB, change forms, and add modules through videos.


Section 10-3

Module/template design with operation in mind

There is a difference between "code that works" and "code that is easy to operate." An hour of ingenuity during development can save dozens of hours of confusion during client operations.

Separation of the areas that marketers touch and the areas that engineers touch

design principlesconcrete implementation
Make things that can be controlled in fields a field. Colors, text, links, and images are all managed in fields.json fields. Allow changes to be made without touching the code.
Always set default values Set meaningful default values ​​for all fields. Even if it is not set, it will maintain a state of ``apparent appearance''.
Make field labels Japanese Do not leave the label in English. Marketers are less confused by "background color" than by "bg_color."
Add input guide with help_text For the image field, write "Recommended size: 1440x640px" and for the text field, write "Up to 0 characters recommended" in help_text.
Restrict fragile operations with choice Make layout switching a selection method using a choice field instead of free input. Prevent input of unexpected values.

How to write fields.json that is easy to operate

fields.json — An example of easy-to-use field design
[
  {
    "type": "text",
    "name": "heading",
    "label": "Heading",
    "required": true,
    "default": "Enter heading text",
    "help_text": "Recommended maximum of 30 characters. If it's too long, your phone will wrap it back."
  },
  {
    "type": "image",
    "name": "bg_image",
    "label": "Background image",
    "help_text": "Recommended size: 1440 x 640px. Please compress to JPG format and 2MB or less.",
    "default": {
      "src": "",
      "alt": "",
      "width": 1440,
      "height": 640
    }
  },
  {
    "type": "choice",
    "name": "layout",
    "label": "Layout",
    "help_text": "Choose where to place the text.",
    "choices": [
      ["center", "Center (default)"],
      ["left",   "Left-aligned"],
      ["right",  "Right alignment"]
    ],
    "default": "center",
    "display": "radio"
  },
  {
    // Fields on STYLE tab are set as "For advanced users"
    // Detach from normal editing screen
    "type": "color",
    "name": "overlay_color",
    "label": "Overlay Color",
    "tab": "STYLE",
    "help_text": "The color to overlay on top of the background image. Transparency can also be set.",
    "default": { "color": "#000000", "opacity": 40 }
  }
]

Comment design for templates

The template file contains information for those who will touch it later (your future self or the engineer who took over). Leave a comment. From “What are you doing?”“Why did you do this?”The general rule is to write

templates/blog-post.html — Examples of easy-to-maintain comments
{#
  =====================================================
Blog article template (blog-post.html)  =====================================================
[Use] Blog article detail page[Inheritance] layouts/base.html[DnD] None (fixed layout)
[Update history]2024-03-15 v1.2 Added content type form switching2024-01-10 v1.1 Added previous/next article navigation2023-11-01 v1.0 initial release
[Notes]- For tag naming rules, refer to "Tag Design" in README.md- The form ID is managed in the form_config dictionary in this file.- If you want to add a form, add it to form_config  =====================================================
#}
{% extends "./layouts/base.html" %}

{# ===== Content type determination =====
   Determine the type by the tag prefix.
   See Chapter 6, "Tag Design Strategies" for details.
   type: If multiple tags are attached, the last value found will be used (only one is recommended for operational purposes)
===================================================== #}
{% set ns = namespace(content_type="blog") %}
{% for tag in content.tag_list %}
  {% if tag.slug starts_with "type:" %}
    {% set ns.content_type = tag.slug|replace("type:","") %}
  {% endif %}
{% endfor %}

{# ===== Form settings dictionary =====
   Manage form IDs and redirect destinations for each content type.
   When adding a new type, just add it here.
   The form ID can be found in the form details URL on the HubSpot admin screen.
===================================================== #}
{% set form_config = {
  "blog"       : { "id": "BLOG_FORM_ID",       "redirect": "/thanks/contact"    },
  "seminar"    : { "id": "SEMINAR_FORM_ID",    "redirect": "/thanks/seminar"    },
  "whitepaper" : { "id": "WHITEPAPER_FORM_ID", "redirect": "/thanks/whitepaper" }
} %}

Section 10-4

Coding and commenting conventions

When developing and maintaining code as a team, if there are no rules, the way the code is written will be inconsistent. Maintenance costs will increase.At least a clear written agreementis required.

HubSpot CMS Development Coding Standards (Recommended Template)

CODING_RULES.md — Coding rules document template
# HubSpot CMS Coding Standards
## File/directory naming conventions- File name/directory name: kebab-case (e.g. hero-banner, blog-post)- Module name: kebab-case + .module (e.g. hero-banner.module)- CSS class name: BEM (Block__Element--Modifier)- HubL variable name: snake_case (e.g. content_type, form_id)
## HubL Terms
### Variable definition- Define variables used outside the loop all at the beginning- Define the dictionary (map) with set and then refer to it- Use namespace (ns) only in stateful loop processing
### Template comments- Start of file: Enter purpose, update history, and notes (required)- Complex logic: write “why you did this” (you can understand what you are doing by reading it)- TODO: Make it easier to search with the "TODO:" prefix
### Existence check principle- image field: Check with {% if module.image.src %}- link field: Check with {% if module.link.url %}- Text: Check with {% if module.text %}- Do not refer to .src etc. without checking its existence
## CSS conventions
### Naming Convention (BEM).module-name {}              ← Block
.module-name__element {}     ← Element
.module-name--modifier {}    ← Modifier
.module-name__element--mod{} ← Element + Modifier

### Responsive- Mobile first (override breakpoints with min-width)- Unify breakpoints with CSS variables  --bp-sm: 480px;
  --bp-md: 768px;
  --bp-lg: 1024px;
  --bp-xl: 1280px;

### CSS variable references- Always refer to theme.json colors and fonts via CSS variables- Do not hardcode direct values ​​(#ff0000, etc.)
## Accessibility Terms- Set alt attribute on all img tags (decorative images are alt="")- Set aria-label on interactive elements- Maintain color contrast ratio at WCAG AA (4.5:1) or higher- Focus can be visually confirmed by keyboard operation
## Git commit message conventionsfeat: New feature addedfix: bug fixstyle: Appearance adjustment (no functional change)refactor: refactoringdocs: Changes to documentation onlydeploy: production deployment (used in conjunction with version tag)

Section 10-5

Responding to HubSpot updates and regular maintenance

HubSpot is a continuously updated platform. By regularly adding features, changing the UI, and responding to deprecations, You can maintain the quality of your site for a long time.

Regular maintenance items and frequency

itemfrequencyContent
CLI version check/update Once a month npm update -g @hubspot/cli Updated to the latest version. Check the change history (CHANGELOG) to see if there are any Breaking Changes.
Check PageSpeed ​​Insights Once a month Records the scores of representative pages (top page, blog list, article details). Check to see if it has worsened compared to the previous month.
Check Search Console once a week Check the coverage error/Core Web Vitals issue page. If there are any new errors, we will respond immediately.
Check for HubSpot product updates Once a month Check out HubSpot's Product Updates page and Developer Changelog at developers.hubspot.com.
Broken link check Once every 3 months Check your entire site for broken links using tools such as Screaming Frog.
Update your Personal Access Key every 150 days Renew the key before it expires (180 days). GitHub Secrets will also be updated at the same time.
Check for deprecation of HubSpot templates Once every six months Check the HubSpot developer documentation to see if any HubL features you're using have been deprecated.

Areas most affected by HubSpot updates

ℹ️ HubSpot developer resources

Developer documentation: developers.hubspot.com/docs/cms
Product updates: www.hubspot.com/product-updates
Developer forum: community.hubspot.com/t5/HubSpot-Developers
GitHub(HubSpot CLI): github.com/HubSpot/hubspot-cli/releases
HubSpot Developer Changelog: developers.hubspot.com/changelog


Section 10-6

Common operational problems and solutions

troubleshooting guide

symptomsWhere to check for the causesolution
the page turned white Previous deployment content/HubL syntax error Check the error with hs lint → check out the previous git tag and rollback
module not visible fields.json syntax error/required field not set Select the module in HubSpot's page editor to see error messages
CSS is not reflected Whether to use browser cache/get_asset_url Clear cache with hard reload (Ctrl+Shift+R). Re-upload using CLI.
form cannot be submitted Form ID accuracy/portal ID matching/ad blocker Check in another browser in incognito mode. Double-check the form ID in your HubSpot admin.
hs upload fails Authentication token expired/network/file path incorrect Re-authenticate with hs auth.--portal Check the flag specification.
HubDB data is not displayed Misprints in table Published status, query conditions, and field names Check if the table is "Published" on the HubDB management screen. Simplify and debug query parameters.
Layout is broken on smartphone Image width/height not specified/CSS flexbox settings Switch to responsive mode and identify elements in Chrome DevTools. Specify aspect-ratio or width/height.
The page's OGP image remains outdated SNS cache Facebook: Clear cache with OG Debugger (developers.facebook.com/tools/debug). Twitter: Check with Card Validator.

Basic techniques for HubL debugging

HubL — Output patterns for debugging
{# ===== Check the contents of the variable =====
   Be sure to delete it in the production environment!
===================================================== #}

{# ① Check the type and value of the variable #}
<pre>{{ module|pprint }}</pre>{# ② Check loop counter #}
{% for item in module.items %}
  {# Output loop status #}
  <p>index:{{ loop.index }} / first:{{ loop.first }} / last:{{ loop.last }} / length:{{ loop.length }}</p>{% endfor %}

{# ③ Confirm conditional branch (output judgment result) #}
<p>content_type: {{ ns.content_type }}</p>
<p>is_featured: {{ ns.is_featured }}</p>{# ④ Check HubDB data #}
{% set rows = hubdb_table_rows("my_table") %}
<p>取得件数: {{ rows|length }}</p>
<pre>{{ rows|pprint }}</pre>{# ⑤ Check request object (URL parameters, etc.) #}
<pre>{{ request|pprint }}</pre>

Section 10-7

Regular performance monitoring

Structure of monthly performance report

If included in a maintenance contract, we will provide reports to the client on a monthly basis. Including the following items will increase credibility.

📊 Monthly performance report items

Core Web Vitals(PageSpeed Insights)

  • Target URL (top page, blog list, article details)
  • LCP/CLS/INP scores and month-on-month changes
  • Items requiring improvement and plans to address them

Search Console Summary

  • Number and type of coverage errors
  • Core Web Vitals “Bad URL” count
  • New errors and response status

GA4 Summary (optional)

  • Monthly change in number of sessions/conversions
  • Bounce rate/average engagement time
  • Number of form submissions (conversions)

Maintenance work performed

  • Contents of corrections/renovations and target pages
  • Deployment date and version
  • Items scheduled for next month

Section 10-8

Long-term operation checklist

🚀 At the time of delivery (just before handover)
hubspot.config.yml is added to .gitignore Cut off the route for Personal Access Keys to leak to the outside world.
watch to production portal not included in package.json Double check that the dev script is pointing towards the development portal.
Created and shared handover documents and module operation guides You've already sent your client a link to Notion or Confluence.
noindex is set on the thanks page Check /thanks/* type pages in Search Console.
The actual GA4/GTM is working correctly Check for gtag requests in the Network tab of Chrome DevTools.
I typed git tag v1.0.0 and recorded the first release commit. Start the habit of tagging your production deployments from here.
📅 Monthly maintenance
Measured and recorded core pages with PageSpeed ​​Insights Recording trends in a spreadsheet makes it easier to notice deterioration.
I saw a coverage error in Search Console If there is a new error, identify the cause and take action.
Checked for HubSpot product updates Check for updates related to the features you use.
Checked the latest version of @hubspot/cli npm outdated -g @hubspot/cli Apply any updates.
🗓️ Semi-annual/annual maintenance
Personal Access Key updated (every 150 days) GitHub Secrets was also updated at the same time. Reset calendar reminders.
Performed broken link check Check for 404 links throughout your site using something like Screaming Frog.
Updated screenshots of transfer documents Check if the HubSpot admin UI has changed and replace old images.
Checked whether the HubL function in use was deprecated. Check out the Deprecated list in the HubSpot developer documentation.

Section 10-9

Textbook Summary: As a HubSpot CMS Developer

📌 Chapter 10 points

Design the maintenance system before delivery

Agree on the division of roles, request flow, and contract details in advance. If we enter the operational phase with ambiguity, misunderstandings will occur.

Tailor the handover document to the reader

For marketers, ``how to operate''. For engineers, ``Why did we design it this way?'' Write a document that separates both perspectives.

Easy-to-operate code is determined by design

help_text/Japanese label/choice input restriction/default value. An hour of care during development can save clients from tens of hours of confusion.

Make regular maintenance a habit

Monthly PageSpeed/Search Console checks and token updates every 150 days. Put it in your calendar and deal with it ``as a system''.

🎓

HubSpot CMS Embedded Construction Textbook — Complete

From the overall picture in Chapter 0 to HubL, templates, modules, data utilization, forms, performance, CLI, and operational design.
The techniques and design concepts learned in this textbook are applicable not only to HubSpot CMS projects, but also to
It is also the answer to the question, "How do I interact with clients as an engineer?"

Code is a tool. Our goal is to advance our client's business.

When you are at a loss in the field, please use this textbook as a dictionary.