Implementations

Migrating HubSpot CMS Pages Between Portals: A Technical Guide

Jetstack Team 15 min read
hubspotmigrationcmshubltemplates

Migrating HubSpot CMS pages between portals is a fundamentally different challenge from migrating CRM data. CRM records are structured, tabular, and can be moved via CSV or API. CMS pages, on the other hand, are tangled webs of content, templates, modules, styles, and code that reference each other in ways that are not always obvious until something breaks.

Templates Modules Page Content Published Page

This guide is written for the technical practitioner — the HubSpot developer, RevOps engineer, or implementation specialist — who needs to move CMS pages from one HubSpot portal to another without losing content, breaking layouts, or introducing rendering errors.

Understanding HubSpot CMS Page Types

HubSpot CMS hosts several distinct page types, each with different migration characteristics.

Page TypeTemplate Dependent?Native Export?API Available?Migration Complexity
Website PagesYesNoYesHigh — template IDs are portal-specific
Landing PagesYesNoYesHigh — drag-and-drop layouts add complexity
Blog PostsPartialRSS import onlyYesMedium — primarily text and images
System PagesYesNoNoLow — manual configuration only

Website Pages

Standard website pages are the core of your HubSpot-hosted site. Each page consists of a template that defines the layout and available content regions, module instances placed within template regions populated with content, page-level settings including URL, meta data, featured image, and publishing status, and style overrides applied at the page or module level.

⚠️
No Native Page Export

Website pages cannot be exported and imported natively between portals. The content, template references, and module configurations must be recreated. This is the single most important fact to understand before starting a CMS migration.

Landing Pages

Landing pages follow the same architecture as website pages but are typically managed in a separate area of HubSpot’s marketing tools. They share the same template and module system. Some landing pages use HubSpot’s drag-and-drop editor with flexible columns, which adds a layer of layout data that is stored separately from the template.

Blog Posts

Blog posts are somewhat easier to migrate because their content is primarily text and images, with less template dependency than website pages. However, the blog configuration, author profiles, tag taxonomy, and template must all be set up in the destination portal before posts can be created.

System Pages

System pages include the 404 error page, password prompt page, email subscription preferences page, and search results page. These are portal-level settings rather than individually addressable pages. They need to be configured manually in the destination portal.

Template Migration: The Foundation Layer

Templates are the foundation of CMS pages. No page can exist without a template, and templates often depend on modules, partials, and stylesheets. Migrating templates first is essential.

Mapping Template Dependencies

Before migrating a single template, map its full dependency tree. This is where most CMS migrations go wrong — missing a single dependency breaks the entire template.

Dependency

Custom Modules

Referenced via {% module %} or {% dnd_module %} HubL tags. Every custom module used by the template must exist in the destination portal.

Dependency

Partials

Reusable template fragments included via {% include %} tags. Missing partials cause render errors.

Dependency

Global Content

Header, footer, and sidebar modules managed at the portal level. These arrive empty in the destination portal and must be manually populated.

Dependency

CSS, JS, and Macros

Stylesheets, scripts, and HubL macros linked from the design manager. Missing assets produce broken layouts or non-functional interactive elements.

Exporting Templates From the Design Manager

1

Navigate to Design Tools

Go to Marketing > Files and Templates > Design Tools (or the newer Developer File System if using CMS CLI).

2

Download Templates and Dependencies

Right-click on a template file and select "Download." Repeat for all dependent modules, partials, CSS, and JS files.

3

Or Use the CMS CLI for Bulk Export

Run hs fetch --portal=source-portal-id ./ to download all design manager files locally, preserving folder structure.

4

Upload to Destination Portal

Upload via UI or CMS CLI: hs upload --portal=destination-portal-id ./ ./. Then verify all template dependencies resolve correctly.

Handling Template ID References

🚨
Portal-Specific IDs Break Cross-Portal Copies

HubSpot templates and modules are referenced internally by numeric IDs, not file paths. When a page references template ID 12345 in the source portal, that ID does not exist in the destination portal. The destination portal assigns its own IDs to uploaded templates. You cannot simply export page data from the source and import it into the destination — template references must be remapped.

Module Migration

Custom modules are the building blocks of HubSpot CMS pages. They define both the content fields that editors can populate and the HTML/HubL/CSS/JS that renders the output.

Custom Module Architecture

Each custom module in HubSpot consists of five files that work together.

FilePurposeMigrates Cleanly?Watch For
fields.jsonDefines content fields (text, image, rich text, groups)YesField types must be supported by destination tier
module.htmlHubL template that renders outputYesPortal-specific variable references
module.cssModule-specific stylesYesFile manager URL references
module.jsModule-specific JavaScriptYesAPI endpoints and portal-specific logic
meta.jsonModule metadata (name, label, icon)YesRarely problematic

Global Modules vs. Local Modules

Global Modules
  • Content stored at the portal level (header, footer, sidebar)
  • Code transfers, but content arrives empty
  • Must manually enter logo, navigation links, footer text
  • Changes affect every page using the module
Local Modules
  • Content stored at the page level
  • Content migrates with the page (via API or manual copy)
  • Each page instance has its own content
  • Changes only affect the specific page

Marketplace Modules

ℹ️
Marketplace Modules Cannot Be Copied

If your source portal uses modules purchased from the HubSpot Marketplace, those modules cannot be copied to the destination portal. You need to purchase or install them separately. Verify that marketplace modules are available for the destination portal's subscription tier. If a module is no longer available, you may need to build a replacement.

Content Migration: Page by Page

With templates and modules in place, the actual page content can be migrated. This is the most labor-intensive phase for content-heavy sites.

Manual Recreation
  • Best for sites with fewer than 50 pages
  • Create each page using the equivalent template
  • Copy content from each module instance
  • Apply page-level settings: URL, meta, featured image
  • Most reliable but most time-consuming
  • Typical speed: 10-20 pages per day
API-Based Migration
  • Best for sites with 50+ pages
  • Fetch pages via GET /cms/v3/pages/site-pages
  • Transform data to remap template and module IDs
  • Create pages via POST /cms/v3/pages/site-pages
  • Faster but requires developer resources
  • Typical speed: hundreds of pages in hours

Manual Recreation

For each page in a manual migration:

1

Create New Page

Create a new page in the destination portal using the equivalent template. Ensure the template has been uploaded and verified before starting.

2

Copy Module Content

Copy content from each module instance in the source page to the corresponding module in the destination page. Pay attention to rich text formatting, image references, and link URLs.

3

Apply Page-Level Settings

Set the URL slug, meta title, meta description, featured image, and canonical URL. These are critical for SEO preservation.

4

Set as Draft

Set publishing status to draft. Do not publish until testing is complete across all migrated pages.

API-Based Migration

The API returns page content as a JSON structure that includes the template reference and all widget (module) data. The widget data uses field names that are consistent between portals, but the template and module references are portal-specific and must be remapped.

Content Staging

📋

HubSpot Content Staging

HubSpot's Content Staging feature (available on Professional and Enterprise tiers) allows you to preview migrated pages in a staging environment, review content accuracy without making pages publicly accessible, and stage a batch of pages for simultaneous publication at go-live.

HubL Considerations

HubL is HubSpot’s proprietary templating language. While HubL code is syntactically identical between portals, there are several portal-specific considerations that can break your templates in the destination environment.

Portal-Specific Variables

HubL VariableWhat It ReturnsMigration RiskAction Required
{{ hub_id }}Portal IDHigh — different in every portalReview all code using this variable
{{ request.domain }}Request domainHigh if domain changesUpdate conditional logic based on domain
{{ content.absolute_url }}Full URL including domainMedium — domain prefix changesUpdate hardcoded domain references

HubDB References

If your templates or modules pull data from HubDB tables, those tables must be recreated in the destination portal. HubDB table IDs are portal-specific, so any HubL function that references a table by ID needs to be updated.

💡
Use Table Names Instead of IDs

Reference HubDB tables by name (hubdb_table_rows(TABLE_NAME)) instead of by ID (hubdb_table_rows(TABLE_ID)). This makes cross-portal migration cleaner since names are portable but IDs are not.

Serverless Functions

HubSpot serverless functions (used in CMS Enterprise) are stored in the design file system and can be downloaded and uploaded like any other file. However, they may reference environment variables, external API endpoints specific to the source environment, and HubSpot API keys or private app tokens tied to the source portal. Review every serverless function for portal-specific references before deploying in the destination portal.

Custom Module Field Dependencies

  • Review blog fields that reference a specific blog by ID
  • Review form fields that reference a specific form by ID
  • Review CTA fields that reference a specific CTA by ID
  • Review menu fields that reference a specific navigation menu by ID
  • Do not assume IDs will match between portals — they never do

All of these IDs are portal-specific. After uploading modules to the destination portal, review field configurations for any hardcoded ID references and update them.

File Manager Migration

The HubSpot file manager hosts images, PDFs, videos, and other media files referenced by CMS pages.

1

Bulk Download Files

Download files from the source portal's file manager using multi-select batch download or the Files API for very large libraries.

2

Upload Preserving Folder Structure

Upload files to the destination portal, preserving the folder structure as closely as possible. If structures differ, you will need to update file references everywhere.

3

Update All URL References

File manager URLs change between portals. Update references in page content (inline images, linked PDFs), template code, module default values, and CSS files.

⚠️
Most Commonly Missed Step

Broken images and dead PDF links are among the first issues users report after go-live. File manager URL mapping is one of the most commonly missed steps in CMS migration. Verify every image and file link after migration.

Blog Migration: Posts, Authors, and Tags

Blog content migration has its own workflow distinct from website pages.

Blog Configuration

Before migrating posts, configure the blog in the destination portal.

  • Blog name and URL structure
  • Listing page template
  • Post template
  • Subscription and notification settings
  • Social sharing defaults
  • Comment settings

Author Profiles and Tag Taxonomy

Create author profiles in the destination portal that match the source portal. Author names, bios, avatars, and slugs should be consistent to preserve author page URLs and prevent SEO disruption. Recreate the tag taxonomy — tags in HubSpot are blog-specific. If tag slugs change, add redirects for tag listing pages (see our SEO redirect checklist).

Post Migration Methods

Small Blogs

Manual Copy-Paste

Feasible for under 30 posts. Copy the content, set URL, meta data, author, tags, and featured image individually.

Medium Blogs

Blog Import Tool

Import from RSS feeds or WordPress XML exports. Formatting may require cleanup, but it handles bulk content efficiently.

Large Blogs

Blog Posts API

Full programmatic access via /cms/v3/blogs/posts. Create posts with all metadata intact, including publish dates.

Regardless of method, verify that publish dates are preserved. HubSpot uses the publish date for blog ordering, and incorrect dates will reorder your blog archive and confuse search engines.

Testing in the Staging Environment

Testing CMS pages is more visual and subjective than testing CRM data. Automated checks catch structural issues, but a human eye is needed for layout and design fidelity.

Visual Regression Testing

  • Layout differences — column widths, spacing, alignment
  • Font rendering — ensure the destination portal has the same fonts loaded
  • Image display — correct images, proper sizing, no broken references
  • Mobile responsiveness — test at multiple breakpoints
  • Interactive elements — accordions, tabs, sliders, forms

Functional Testing

  • Forms submit correctly and create records in the CRM
  • CTAs render and link to the correct destinations
  • Navigation menus include the correct links
  • Search functionality returns results from the migrated content
  • Blog subscription forms work
  • Video embeds play correctly

Performance Testing

Run Lighthouse or PageSpeed Insights on key migrated pages. Compare scores to the source portal.

ℹ️
Common Performance Regressions

Watch for unoptimized images re-uploaded at full resolution, missing CSS/JS minification, render-blocking scripts loaded in a different order, and missing lazy loading on images. These are the most frequent performance issues after CMS migration.

Go-Live and Post-Migration

When testing is complete, go-live follows the process outlined in our complete HubSpot-to-HubSpot migration guide, with CMS-specific additions.

1

DNS Cutover

If the destination portal uses a different domain or subdomain, update DNS records to point to HubSpot's servers. HubSpot provides the CNAME records needed in Domains settings.

2

Redirect Activation

Activate your 301 redirect map in the destination portal. For a complete redirect implementation guide, see our SEO redirect checklist.

3

Cache Clearing

Clear CDN and browser caches to ensure visitors see the new pages immediately. HubSpot's CDN cache typically updates within minutes.

4

Monitor for Two Weeks

Monitor page load times, 404 errors, form submissions, and CMS-specific analytics. Set up alerts for 500 errors, which typically indicate HubL rendering issues in a template.

How Jetstack Supports CMS Migrations

Jetstack’s implementation services include specialized CMS migration support. Our approach covers template dependency mapping, automated content transfer, visual regression testing, and SEO-first redirect management.

For organizations running CMS migration as part of a broader portal migration, our complete migration guide covers the full process end to end. If you need pre-migration assessment, our audit services provide a comprehensive portal review.

Contact our team to discuss your CMS migration project.

Frequently Asked Questions

Can I copy HubSpot CMS pages directly between portals?

No. HubSpot does not provide a native page copy or export feature between portals. Pages must be recreated in the destination portal using the same template structure, with content migrated manually, via API, or using third-party tooling. The template and module IDs are portal-specific, which makes direct copying impossible.

Do I need to recreate all my templates in the new portal?

Yes. Templates, modules, partials, and all design manager files need to be uploaded to the destination portal. While the code transfers directly, all internal ID references (template IDs, module IDs, HubDB table IDs) are portal-specific and may need updating.

What happens to my HubDB data during migration?

HubDB tables do not transfer between portals. You need to recreate the table schema in the destination portal, export data from the source table (via HubDB API or CSV export), and import it into the new table. Update any HubL code that references tables by ID to use the destination portal’s table IDs.

How do I handle marketplace modules during CMS migration?

Marketplace modules cannot be copied between portals. You need to install them in the destination portal through the HubSpot Marketplace. Verify that the destination portal’s subscription tier supports the modules you need. If a marketplace module is no longer available or supported, you may need to build a replacement.

Will my page publish dates be preserved after migration?

If you use the API to create pages, you can set the publish date explicitly. Manual recreation also allows you to set the publish date. The critical step is ensuring you capture the original publish dates before migration and apply them in the destination portal. Incorrect publish dates affect blog ordering and can confuse search engines.

How long does a typical CMS migration take?

Duration depends on the number of pages, the complexity of the template system, and whether HubDB, serverless functions, or custom modules are involved. A 50-page site with standard templates typically takes two to three weeks. A 500-page site with complex custom modules, HubDB, and serverless functions can take six to eight weeks.

Ready when you are

Less busywork. More delivery, everywhere.

See how JetStack AI turns weeks of manual ops into minutes.
Book a demo now. No commitment, no sales pitch.

Free trial
Set up in under 5 minutes
Works with your existing portal