# Uniform Siphon - Contentful CMS Migration Walkthrough

> Complete guide for migrating from Contentful CMS to Uniform using Siphon tools

Source: https://docs.uniform.app/docs/guides/migration/contentful/walkthrough

This guide walks you through the complete process of migrating content and assets from Contentful CMS to the Uniform platform using Uniform Siphon tools.

## Table of Contents

1. [Prerequisites](#prerequisites)
2. [Installation and Setup](#installation-and-setup)
3. [Phase 1: Download Contentful Data](#phase-1-download-contentful-data)
4. [Phase 2: Migration to Uniform](#phase-2-migration-to-uniform)
5. [Assessment and Validation](#assessment-and-validation)
6. [Advanced Topics](#advanced-topics)

---

## Overview

The migration process happens in 4 logical steps:

- Source content and media is downloaded from Conetntful with `contentful-cli` to a Windows machine
- Content are processed with `Siphon.Migration.Contentful.exe` and Uniform files are produced
- Media files are pushed to Uniform project using `Siphon.Migration.Contentful.exe`
- Uniform files are pushed to Uniform using Uniform CLI (`@uniformdev/cli`)

## Prerequisites

### System Requirements

1. **Windows machine**
2. **Direct HTTP access** to Contentful space and Uniform project

### Recommendations

- Use PowerShell for running command-line tools
- Ensure sufficient disk space for downloaded content

---

## Installation and Setup

### 1. Extract Siphon Tools

Extract all `siphon-*-XXXXXXX-X.zip` distribution packages provided by Uniform to a local folder:

```powershell
# Recommended location
C:\siphon
```

### 2. Prepare work directory

Create a work directory for all files will be downloaded and processed, for example: `C:\migration\`.

Open a new PowerShell session and navigate there:

```powershell
PS C:\migration> cd C:\migration
PS C:\migration>
```

### 4. Use environment variables

It is recommended to create `.env` file in the work directory and use environment variables instead of command-line arguments.

Environment variables can be used instead of command-line arguments:

- `SIPHON_{PARAMETER}` works with all Siphon executables and all commands that have particular parameter,
- `SIPHON_{COMMAND}_{PARAMETER}`: works only with `{COMMAND}` that have particular parameter within `Siphon.Migration.Contentful.exe`.

For example:

```powershell
# equivalent of --inputDir for all Siphon commands
# it will work for C:\siphon\Siphon.Migration.Contentful.exe uniform-content
# it will work for C:\siphon\Siphon.Migration.exe uniform-content
$env:SIPHON_INPUTDIR='C:\migration\contentful'

# equivalent of $env:SIPHON_INPUTDIR for uniform-content command only
$env:SIPHON_UNIFORM_CONTENT_INPUTDIR='C:\migration\contentful'
```

Siphon reads `.env` files from:

- Current working directory
- Siphon executable directory

### 5. Configure Logging

Set up PowerShell logging for the entire session:

```powershell
PS C:\migration> Start-Transcript -Path "C:\migration\siphon.log" -Append
```

#### Log Levels

All commands accept `--logLevel` parameter with these values:

- `debug` - Includes all types (default)
- `info` - Also includes `warn` and `error`
- `warn` - Also includes `error`
- `error` - Only error messages

---

## Phase 1: Download Contentful Data

### 1.1 Prepare a work directory

Create a work directory for all files will be downloaded and processed, for example: `C:\migration\contentful`.

Open a new PowerShell session and navigate there:

```powershell
PS C:\migration> cd C:\migration\contentful
PS C:\migration>
```

### Step 1: Install Contentful CLI

```powershell
PS C:\migration> npm install -g contentful-cli
```

### 1.2 Download Content

Download contentful content using the `contentful-cli`.

#### Basic Command Structure

The export produces a JSON file for content, plus assets folders with binary files.

```powershell
PS C:\migration\contentful> contentful space export `
  --space-id $SPACE_ID `
  --environment-id $ENVIRONMENT_ID `
  --management-token $CMA_TOKEN `
  --delivery-token $CDA_TOKEN `
  --download-assets
```

#### Parameters

| Parameter | Description |
| --- | --- |
| `--space-id` | ID of Space with source data |
| `--environment-id` | ID of Environment with source data, default: `master`. |
| `--management-token` | Contentful management API token. |
| `--delivery-token` | Contentful delivery API token - Required for published content migration, without this token the latest content from the space will be migrated. |
| `--download-assets` | With this flags assets will also be downloaded. |

---

## Phase 2: Migration to Uniform

Migrate content entries and content types from Contentful to **Uniform Content Entries**. The process transforms the extracted data from Contentful and pushes it to the Uniform platform.

### Pre-requisites:

- Ensure that the download of Contentful data is complete.
- Prepare a Uniform Project and manually add all languages that were previously downloaded
- Set up a **Uniform Content** Data Source in your Uniform project
- Create an API Key with a `Developer` role

### 2.1 Migrate to Content

Transform Contentful content types and entries into Uniform Content content types and entries.

```powershell
PS C:\migration> C:\siphon\Siphon.Migration.Contentful.exe uniform-content `
  --outputDir C:\migration\uniform `
  --inputDir C:\migration\contentful `
  --languages "en-US" `
  --dataSourceId "content" `
  --slugFieldId "slug"
```

#### Required Parameters

| Parameter | Description |
| --- | --- |
| `--inputDir` | Downloaded Contentful data folder |
| `--outputDir` | Uniform content output folder |

#### Optional Parameters

| Parameter | Description |
| --- | --- |
| `--dataSourceId` | Uniform Content Data Source ID, for example: `content` |
| `--slugFieldId` | Field name in the Contentful entry that will be used for the Uniform entry slug |
| `--languages` | Limit to specific languages (e.g., `en-US,da-DK`), empty value means migrate content in all registered languages (default: empty) |
| `--json-seo-field` | Set SEO field id. If the SEO field is JSON, it will analyze all values to find all possible fields and create a separate field for each of them in as SEO block |

### 2.2 Push Content Data

Deploy content entries to Uniform platform.

```powershell
cd C:\migration\uniform
npm run uniform:push:content

# For parallel processing (4 threads)
npm run uniform:push:content-p4
```

### 2.3 Upload Assets

Upload media assets to Uniform Asset Library.

```powershell
PS C:\migration> C:\siphon\Siphon.Migration.Contentful.exe uniform-upload-asset `
  --inputDir C:\migration\contentful `
  --UNIFORM_API_KEY "your_api_key" `
  --UNIFORM_PROJECT_ID "your_project_id" `
  --languages "en-US" `
  --skipUnusedMedia
```

#### Required Parameters

| Parameter | Description |
| --- | --- |
| `--inputDir` | Downloaded files folder |
| `--UNIFORM_API_KEY` | Uniform API key |
| `--UNIFORM_PROJECT_ID` | Uniform Project ID |

#### Optional Parameters

| Parameter | Description |
| --- | --- |
| `--languages` | Limit to specific languages (e.g., `en-US,da-DK`), empty value means migrate content in all registered languages (default: empty) |
| `--skipUnusedMedia` | Upload only media directly referenced by previously-downloaded content (default: `false`) |
| `--threads` | Upload threads (default: 4) |

---

## Assessment and Validation

### Analyzing Migration Results

To assess migration quality, analyze the log files:

1. **Re-run with warnings only**:

   ```powershell
   C:\siphon\Siphon.Migration.Contentful.exe uniform-content [params] --logLevel Warn | Tee-Object .\assessment.txt
   ```
2. **Review in text editor**:

   - Open `assessment.txt` in Notepad++
   - Menu → Edit → Line Operations → Remove duplicate lines
   - Review each unique warning/error
3. **Common issues to check**:

   - Missing field mappings
   - Unsupported field types
   - Reference resolution failures
   - Language-specific problems

---

## Advanced Topics

### Transformation Commands

Siphon includes various transformation commands for post-migration cleanup and optimization.

#### Contentful: Migrate Inline Assets (Experimental)

This utility processes Uniform serialization exported from **Contentful** and migrates inline Contentful asset URLs into **Uniform assets**.  
It scans entries, compositions, and component parameters for embedded Contentful asset URLs (e.g., `ctfassets.net/...`) and replaces them with Uniform asset references.  
If Uniform project credentials are provided, missing assets can also be uploaded automatically.

```powershell
contentful-migrate-inline-assets --contentfulExportFolder <contentful_export_path> --inputDir <uniform_path> --outputDir <output_path>
```

#### Required Parameters

| Parameter | Description |
| --- | --- |
| `--contentfulExportFolder` | Path to the Contentful export folder (JSON + assets) |
| `--inputDir` | Path to the folder containing Uniform serialization data (`entry`, etc.) |
| `--outputDir` | Path to the folder where transformed data will be written |

#### Optional Parameters

| Parameter | Description |
| --- | --- |
| `--UNIFORM_API_KEY` | Uniform API key (required for asset upload to Uniform) |
| `--UNIFORM_PROJECT_ID` | Uniform Project ID (required for asset upload to Uniform) |
| `--UNIFORM_CLI_BASE_URL` | Uniform CLI base URL (default: _For the US region:_<br>_For the EU region:_<br>) |
| `--logLevel` | Sets the log level. Options: `debug`, `info`, `warn`, `error` (default: `debug`) |
| `--no-timestamps` | Disable timestamps in logs |

---

#### Contentful: Replace Image URL Field (Experimental)

This utility processes Uniform serialization exported from **Contentful** and replaces fields that contain **raw Contentful image URLs** with proper **Uniform asset fields**.  
It is useful when Contentful exports store images as plain text fields or image URLs, and you want to migrate them into Uniform’s structured asset model.

```powershell
contentful-replace-image-url-field --contentfulExportFolder <contentful_export_path> --inputDir <uniform_path> --outputDir <output_path> --textFields imageReference|mobileImageReference
```

#### Required Parameters

| Parameter | Description |
| --- | --- |
| `--contentfulExportFolder` | Path to the Contentful export folder (JSON + assets) |
| `--inputDir` | Path to the folder containing Uniform serialization data (`entry`, etc.) |
| `--outputDir` | Path to the folder where transformed data will be written |

#### Optional Parameters

| Parameter | Description |
| --- | --- |
| `--textFields` | Comma/semicolon/pipe-delimited list of text field IDs to migrate into asset fields. Example: `imageReference |
| `--logLevel` | Sets the log level. Options: `debug`, `info`, `warn`, `error` (default: `debug`) |
| `--no-timestamps` | Disable timestamps in logs |

---

#### Contentful: Replace Datatype with Components (Experimental)

This utility processes a Uniform serialization dataset and replaces **Contentful datatypes** (singleEntry / multipleEntry) with **components and patterns**.  
It migrates data from a specified datasource (`datatypeId`) into components, embedding entry content directly and generating new patterns if needed.  
This allows phasing out `datatype` dependencies and making components self-contained.

```powershell
contentful-replace-datatype-with-components --inputDir <uniform_path> --outputDir <output_path> --contentfulExportFolder <contentful_export_path> --datatypeId <datatypeid> --datatypeType <datatypeType>  --componentId <componentId>
```

#### Required Parameters

| Parameter | Description |
| --- | --- |
| `--inputDir` | Path to the folder containing Uniform serialization (`composition`, `pattern`, etc.) |
| `--outputDir` | Path to the folder where transformed data will be written |
| `--contentfulExportFolder` | Path to the Contentful export folder (JSON + assets) |
| `--datatypeId` | The ID of the existing datatype to be replaced (e.g., `blogPosts`) |
| `--datatypeType` | Type of the datatype. Supported: `contentful` |
| `--componentId` | Target component ID that will replace the datatype |

#### Optional Parameters

| Parameter | Description |
| --- | --- |
| `--languages` | Languages to include. If not set, all languages will be processed |
| `--logLevel` | Sets the log level. Options: `debug`, `info`, `warn`, `error` (default: `debug`) |
| `--no-timestamps` | Disable timestamps in logs |

---

#### Contentful: Find Orphaned Data Resources (Experimental)

Scans a Uniform serialization and the linked **Contentful export** to find **orphaned data resources** — i.e., Contentful data resources that reference entry IDs which **don’t exist** in the export.  
Supports both **singleEntry** and **multipleEntry** archetypes. Checks data resources defined at the composition/entry level and inside **overrides**.

```powershell
contentful-find-orphaned-dataresources --inputDir <uniform_path> --contentfulExportFolder <contentful_export_path>
```

#### Required Parameters

| Parameter | Description |
| --- | --- |
| `--inputDir` | Path to the folder containing Uniform serialization (`composition`, `entry`, etc.) |
| `--contentfulExportFolder` | Path to the **Contentful** export folder (must include JSON and assets) |

#### Optional Parameters

| Parameter | Description |
| --- | --- |
| `--datasourceId` | Limit the scan to a specific datasource ID. If omitted, **all** datasources are checked. |
| `--logLevel` | Log verbosity: `debug`, `info`, `warn`, `error` (default: `debug`) |
| `--no-timestamps` | Disable timestamps in logs |

---

#### Contentful: Replace Datatype (Experimental)

Migrates a Uniform project from one **datasource provider** to another by:

- Re-creating _datatype_ definitions under the new provider, and
- Rewriting **dataResources** and **JPTR tokens** in compositions/entries to the new pointer format.

Supports **singleEntry** and **multipleEntry** archetypes for Contentful exports.

```powershell
contentful-replace-datatype --inputDir <uniform_path> --outputDir <output_path> --contentfulExportFolder <contentful_export_path> --datasourceId <source_datasource_id> --new-datasourceId <target_datasource_id>
```

#### Required Parameters

| Parameter | Description |
| --- | --- |
| `--inputDir` | Path to the folder containing Uniform serialization (`composition`, `entry`, `datatype`, etc.) |
| `--outputDir` | Path to the folder where transformed data will be written |
| `--contentfulExportFolder` | Path to the Contentful export folder (JSON + assets) |
| `--datasourceId` | ID of the **existing** datasource to migrate (must include `singleEntry` / `multipleEntry` datatypes) |
| `--new-datasourceId` | ID of the **target** datasource provider to migrate to |

#### Optional Parameters

| Parameter | Description |
| --- | --- |
| `--logLevel` | Log verbosity: `debug`, `info`, `warn`, `error` (default: `debug`) |
| `--no-timestamps` | Disable timestamps in logs |

---

For additional support, contact Uniform support with detailed log files and error messages.
