diff --git a/src/Component/Helper/FillPdfMappingHelper.php b/src/Component/Helper/FillPdfMappingHelper.php
index 3003158eb7f01922bb210d82210a874e1ec29faa..611046e6e387f780f1e65318cf36b9153f7599e6 100644
--- a/src/Component/Helper/FillPdfMappingHelper.php
+++ b/src/Component/Helper/FillPdfMappingHelper.php
@@ -9,8 +9,18 @@ namespace Drupal\fillpdf\Component\Helper;
  */
 class FillPdfMappingHelper {
 
+  /**
+   * Parses replacements.
+   *
+   * @param string $replacements_string
+   *   The replacements string.
+   *
+   * @return string[]
+   *   Associative array of replacement values, keyed by the value to be
+   *   replaced.
+   */
   public static function parseReplacements($replacements_string) {
-    if (empty($replacements_string) !== TRUE) {
+    if (!empty($replacements_string)) {
       $standardized_replacements = str_replace([
         "\r\n",
         "\r",
@@ -20,7 +30,8 @@ class FillPdfMappingHelper {
       foreach ($lines as $replacement) {
         if (!empty($replacement)) {
           $split = explode('|', $replacement);
-          if (count($split) == 2) { // Sometimes it isn't; don't know why.
+          // Sometimes it isn't; don't know why.
+          if (count($split) == 2) {
             $return[$split[0]] = preg_replace('|<br />|', '
 ', $split[1]);
           }
@@ -34,27 +45,25 @@ class FillPdfMappingHelper {
   }
 
   /**
-   * @param $value
-   * The value to replace. Must match the key in a replacements field exactly.
-   * @param $form_replacements
-   * A list of replacements with form-level priority.
-   * @param $field_replacements
-   * A list of replacements with field-level priority. These have precedence.
-   * @return string $value with any matching replacements applied.
+   * Applies form and field level replacements to a string.
+   *
+   * @param string $value
+   *   The value to replace. Must match the key in a replacements field exactly.
+   * @param array $form_replacements
+   *   A list of form-level replacements.
+   * @param array $field_replacements
+   *   A list of field-level replacements. These have precedence.
+   *
+   * @return string
+   *   $value with any matching replacements applied.
+   *
+   * @deprecated in fillpdf:8.x-4.7 and will be removed from fillpdf:8.x-5.0.
    */
-  public static function transformString($value, $form_replacements, $field_replacements) {
-    if (empty($form_replacements) && empty($field_replacements)) {
-      return $value;
-    }
-    elseif (!empty($field_replacements) && isset($field_replacements[$value])) {
-      return $field_replacements[$value];
-    }
-    elseif (!empty($form_replacements) && isset($form_replacements[$value])) {
-      return $form_replacements[$value];
-    }
-    else {
-      return $value;
-    }
+  public static function transformString($value, array $form_replacements, array $field_replacements) {
+    @trigger_error('transformString is deprecated in fillpdf:8.x-4.7 and will be removed from fillpdf:8.x-5.0. See https://www.drupal.org/project/fillpdf/issues/3044743', E_USER_DEPRECATED);
+    // Merge both with field-level replacements taking precedence.
+    $replacements = array_merge($form_replacements, $field_replacements);
+    return isset($replacements[$value]) ? $replacements[$value] : $value;
   }
 
 }
diff --git a/src/Controller/HandlePdfController.php b/src/Controller/HandlePdfController.php
index c0382a8aeb06ae35d68e96fc45cd010e855270c8..155ed6eebc0b01d0188d2a22bf6ddc7148ce056f 100644
--- a/src/Controller/HandlePdfController.php
+++ b/src/Controller/HandlePdfController.php
@@ -129,6 +129,7 @@ class HandlePdfController extends ControllerBase {
     // @todo: Emit event (or call alter hook?) before populating PDF.
     // Rename fillpdf_merge_fields_alter() to fillpdf_populate_fields_alter().
     $fillpdf_form = FillPdfForm::load($context['fid']);
+    $form_replacements = FillPdfMappingHelper::parseReplacements($fillpdf_form->replacements->value);
     $fields = $fillpdf_form->getFormFields();
 
     // Populate entities array based on what user passed in.
@@ -202,17 +203,19 @@ class HandlePdfController extends ControllerBase {
         }
 
         if (!$is_image_token) {
+          // Resolve tokens.
           $replaced_string = $this->tokenResolver->replace($fill_pattern, $entities);
 
-          // Apply field transformations.
           // Replace <br /> occurrences with newlines.
           $replaced_string = preg_replace('|<br />|', '
 ', $replaced_string);
 
-          $form_replacements = FillPdfMappingHelper::parseReplacements($fillpdf_form->replacements->value);
-          $field_replacements = FillPdfMappingHelper::parseReplacements($field->replacements->value);
-
-          $replaced_string = FillPdfMappingHelper::transformString($replaced_string, $form_replacements, $field_replacements);
+          // Apply transformations with field-level replacements taking
+          // precedence over form-level replacements.
+          $field_replacements = FillPdfMappingHelper::parseReplacements($field->replacements->value) + $form_replacements;
+          if (isset($field_replacements[$replaced_string])) {
+            $replaced_string = $field_replacements[$replaced_string];
+          }
 
           // Apply prefix and suffix, if applicable.
           if (isset($replaced_string) && $replaced_string) {
diff --git a/tests/src/Functional/PdfPopulationTest.php b/tests/src/Functional/PdfPopulationTest.php
index 2590efe1fff6925f08c1753ba289f6fd7aba8c35..7ac636d6ef07d0fa003d9a4b4a494ae94715636d 100644
--- a/tests/src/Functional/PdfPopulationTest.php
+++ b/tests/src/Functional/PdfPopulationTest.php
@@ -46,9 +46,17 @@ class PdfPopulationTest extends FillPdfTestBase {
   public function testPdfPopulation() {
     $this->uploadTestPdf('fillpdf_test_v3.pdf');
     $this->assertSession()->pageTextContains('New FillPDF form has been created.');
+
+    // Load the FillPdf Form and add a form-level replacement.
     $fillpdf_form = FillPdfForm::load($this->getLatestFillPdfForm());
+    $fillpdf_form->replacements = 'Hello & how are you?|Hello & how is it going?';
+    $fillpdf_form->save();
 
+    // Get the field definitions for the form that was created and configure
+    // them.
+    $this->mapFillPdfFieldsToNodeFields($fillpdf_form->getFormFields());
 
+    // Create a node to populate the FillPdf Form.
     $node = $this->createNode([
       'title' => 'Hello & how are you?',
       'type' => 'article',
@@ -59,10 +67,6 @@ class PdfPopulationTest extends FillPdfTestBase {
       'type'      => 'page',
     ]);
 
-    // Get the field definitions for the form that was created and configure
-    // them.
-    $this->mapFillPdfFieldsToNodeFields($fillpdf_form->getFormFields());
-
     // Hit the generation route, check the results from the test backend plugin.
     $fillpdf_route = Url::fromRoute('fillpdf.populate_pdf', [], [
       'query' => [
@@ -78,7 +82,7 @@ class PdfPopulationTest extends FillPdfTestBase {
       ->get('fillpdf_test.last_populated_metadata');
 
     self::assertEquals(
-      "Hello & how are you?",
+      'Hello & how are you doing?',
       $populate_result['field_mapping']['fields']['TextField1'],
       'PDF is populated with the title of the node with all HTML stripped.'
     );
@@ -230,6 +234,7 @@ class PdfPopulationTest extends FillPdfTestBase {
         case 'TextField1':
         case 'Text1':
           $field->value = '[node:title]';
+          $field->replacements = 'Hello & how are you?|Hello & how are you doing?';
           break;
 
         case 'TextField2':
@@ -267,8 +272,6 @@ class PdfPopulationTest extends FillPdfTestBase {
    * @throws \PHPUnit_Framework_SkippedTestError
    *   Thrown when test had to be skipped as local pdftk install is not
    *   available.
-   *
-   * @todo Implementation missing.
    */
   public function testMergePdftk() {
     $this->configureFillPdf(['backend' => 'pdftk']);