diff --git a/components/DataLiberation/Tests/RewriteUrlsTest.php b/components/DataLiberation/Tests/RewriteUrlsTest.php
index 17aca6d5..3b947432 100644
--- a/components/DataLiberation/Tests/RewriteUrlsTest.php
+++ b/components/DataLiberation/Tests/RewriteUrlsTest.php
@@ -213,6 +213,30 @@ public static function provider_test_wp_rewrite_urls() {
'https://🚀-science.com/science',
'https://science.wordpress.org',
),
+ 'Fragment-only reference in an HTML attribute is left alone' => array(
+ 'Jump',
+ 'Jump',
+ 'https://legacy-blog.com',
+ 'https://modern-webstore.org',
+ ),
+ 'Bare hash in an HTML attribute is left alone' => array(
+ 'Placeholder',
+ 'Placeholder',
+ 'https://legacy-blog.com',
+ 'https://modern-webstore.org',
+ ),
+ 'Fragment-only reference in a block attribute is left alone' => array(
+ '',
+ '',
+ 'https://legacy-blog.com',
+ 'https://modern-webstore.org',
+ ),
+ 'Absolute URL carrying a fragment is still rewritten and keeps its fragment' => array(
+ 'Deep link',
+ 'Deep link',
+ 'https://legacy-blog.com',
+ 'https://modern-webstore.org',
+ ),
);
}
diff --git a/components/DataLiberation/URL/functions.php b/components/DataLiberation/URL/functions.php
index fe931ce3..daecc82d 100644
--- a/components/DataLiberation/URL/functions.php
+++ b/components/DataLiberation/URL/functions.php
@@ -70,7 +70,20 @@ function wp_rewrite_urls( $options ) {
while ( $p->next_url() ) {
$token_type = $p->get_token_type();
$raw_url = $p->get_raw_url();
- $cache_key = $mapping_cache_key . "\0" . $token_type . "\0" . $raw_url;
+
+ /*
+ * Leave fragment-only references alone. A URL like `#section` points
+ * within the document that contains it, so there is no origin to
+ * migrate. Resolving it against the base URL makes it look like a
+ * child of the site being imported from, and rewriting it then turns
+ * an in-page anchor into a link somewhere else entirely:
+ * `#section` becomes `/#section`, and a bare `#` becomes `/`.
+ */
+ if ( is_string( $raw_url ) && 0 === strpos( $raw_url, '#' ) ) {
+ continue;
+ }
+
+ $cache_key = $mapping_cache_key . "\0" . $token_type . "\0" . $raw_url;
$cached = $rewrite_cache->get( $cache_key );
if ( null !== $cached ) {