# 20-Apr-2026 — Image Migration → Content Migration

## GitHub [#206](https://github.com/nbarrett/ngx-ramblers/issues/206) — [commit 1529096](https://github.com/nbarrett/ngx-ramblers/commit/1529096d6687c5aaea720595c4973f57999a2986)

_____

The admin migration tool now handles **all external document types** — PDFs, Word, Excel and other files — not just images. The admin menu and route are renamed from **Image Migration** to **Content Migration**, with the old URL redirecting automatically.

## What's scanned

The scanner now picks up external URLs from:

- markdown links `[text](https://ngx-ramblers.org.uk/url)`
- HTML links `<a href>`
- image tags and markdown images
- `href` fields on content columns

Each result is tagged with a document type (image, pdf, spreadsheet, document, other) and rendered with an appropriate coloured badge and icon.

### Scan Results

![](https://ngx-ramblers.org.uk/api/aws/s3/site-content/63c9f512-397b-4fa1-8297-51714ab7db8b.jpg)

*Scan Results for kentramblers.org.uk — 478 external items across 225 sources. Coloured badges distinguish PDFs from Word documents; Select All / Deselect All / Migrate N Selected Items live in the toolbar.*

### Activity

![](https://ngx-ramblers.org.uk/api/aws/s3/site-content/26979fbb-3bf4-46ff-88cd-6818c1652447.jpg)

*The Activity tab streams each step of a migration in real time. PDFs download to S3 as-is (no resizing); HTTP failures are surfaced inline but don't halt the batch.*

## Notes

- Non-image files are uploaded to S3 as-is. "Auto Resize Images" only applies to images.
- Link rewriting covers `<img>` / `![]()` and `<a href>` / `[text](https://ngx-ramblers.org.uk/url)` patterns, plus `column.href`.
- The old `admin/image-migration` URL automatically redirects to `admin/content-migration`.
- A deployment migration (`20260329000000`) renames the admin menu item automatically.

## Renames (for contributors)

Everything with "image" in its name has been broadened to "content":

- **Components** — `ImageMigrationTab` → `ContentMigrationTab`; `ImageMigrationGroupComponent` → `ContentMigrationGroupComponent`
- **Types** — `ExternalImageReference` → `ExternalContentReference` (adds `documentType`); new `ContentMigrationDocumentType` enum (`IMAGE`, `PDF`, `SPREADSHEET`, `DOCUMENT`, `OTHER`)
- **Fields** — `images` → `items`, `totalImages` → `totalItems`, `processedImages` → `processedItems`, `currentImage` → `currentItem`, `migratedImages` → `migratedItems`, `failedImages` → `failedItems`
- **Helpers** — `extractImageUrlsFromMarkdown` → `extractExternalUrlsFromText` (also matches links), `extractImagesFromColumn` → `extractUrlsFromColumn` (also scans `href`), `scanForExternalImages` → `scanForExternalContent`, `downloadExternalImage` → `downloadExternalContent`
- **Websocket events** — `IMAGE_MIGRATION_*` → `CONTENT_MIGRATION_*`
- **New helpers** — `documentTypeFromUrl()`, `isExternalDocumentUrl()`