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.
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 Type | Template Dependent? | Native Export? | API Available? | Migration Complexity |
|---|---|---|---|---|
| Website Pages | Yes | No | Yes | High — template IDs are portal-specific |
| Landing Pages | Yes | No | Yes | High — drag-and-drop layouts add complexity |
| Blog Posts | Partial | RSS import only | Yes | Medium — primarily text and images |
| System Pages | Yes | No | No | Low — 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.
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.
Custom Modules
Referenced via {% module %} or {% dnd_module %} HubL tags. Every custom module used by the template must exist in the destination portal.
Partials
Reusable template fragments included via {% include %} tags. Missing partials cause render errors.
Global Content
Header, footer, and sidebar modules managed at the portal level. These arrive empty in the destination portal and must be manually populated.
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
Navigate to Design Tools
Go to Marketing > Files and Templates > Design Tools (or the newer Developer File System if using CMS CLI).
Download Templates and Dependencies
Right-click on a template file and select "Download." Repeat for all dependent modules, partials, CSS, and JS files.
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.
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
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.
| File | Purpose | Migrates Cleanly? | Watch For |
|---|---|---|---|
| fields.json | Defines content fields (text, image, rich text, groups) | Yes | Field types must be supported by destination tier |
| module.html | HubL template that renders output | Yes | Portal-specific variable references |
| module.css | Module-specific styles | Yes | File manager URL references |
| module.js | Module-specific JavaScript | Yes | API endpoints and portal-specific logic |
| meta.json | Module metadata (name, label, icon) | Yes | Rarely problematic |
Global Modules vs. Local 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
- 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
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.
- 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
- 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:
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.
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.
Apply Page-Level Settings
Set the URL slug, meta title, meta description, featured image, and canonical URL. These are critical for SEO preservation.
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 Variable | What It Returns | Migration Risk | Action Required |
|---|---|---|---|
{{ hub_id }} | Portal ID | High — different in every portal | Review all code using this variable |
{{ request.domain }} | Request domain | High if domain changes | Update conditional logic based on domain |
{{ content.absolute_url }} | Full URL including domain | Medium — domain prefix changes | Update 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.
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.
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.
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.
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.
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
Manual Copy-Paste
Feasible for under 30 posts. Copy the content, set URL, meta data, author, tags, and featured image individually.
Blog Import Tool
Import from RSS feeds or WordPress XML exports. Formatting may require cleanup, but it handles bulk content efficiently.
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.
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.
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.
Redirect Activation
Activate your 301 redirect map in the destination portal. For a complete redirect implementation guide, see our SEO redirect checklist.
Cache Clearing
Clear CDN and browser caches to ensure visitors see the new pages immediately. HubSpot's CDN cache typically updates within minutes.
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.