diff --git a/src/Context/FieldResolver.php b/src/Context/FieldResolver.php
index 5c31f40..6f3ad88 100644
--- a/src/Context/FieldResolver.php
+++ b/src/Context/FieldResolver.php
@@ -7,6 +7,8 @@ use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\Entity\FieldableEntityInterface;
 use Drupal\Core\Field\TypedData\FieldItemDataDefinition;
+use Drupal\Core\TypedData\DataReferenceDefinition;
+use Drupal\Core\TypedData\DataReferenceDefinitionInterface;
 use Drupal\Core\TypedData\DataReferenceTargetDefinition;
 use Drupal\jsonapi\ResourceType\ResourceType;
 use Drupal\jsonapi\ResourceType\ResourceTypeRepositoryInterface;
@@ -139,14 +141,32 @@ class FieldResolver {
         ));
       }
 
+      // Determine if the next path part is a sub-property of the field.
+      if (!empty($parts) && static::isCandidateDefinitionProperty($parts[0], $candidate_definitions)) {
+        $reference_breadcrumbs[] = $field_name;
+        // If the property is a reference, then we can continue resolving the
+        // path.
+        if (static::isReferenceProperty($parts[0], $candidate_definitions)) {
+          $reference_breadcrumbs[] = array_shift($parts);
+          continue;
+        }
+        // If it is not a reference, then the remaining parts must all be
+        // sub-properties, not subsequent fields.
+        return $this->constructInternalPath($reference_breadcrumbs, $parts);
+      }
+
       // Get all of the referenceable resource types.
       $resource_types = $this->getReferenceableResourceTypes($candidate_definitions);
 
       // Keep a trail of entity reference field names.
       $reference_breadcrumbs[] = $field_name;
+      if (!empty($parts)) {
+        $reference_breadcrumbs[] = 'entity';
+      }
 
-      // $field_name may not be a reference field. In that case we should treat
-      // the rest of the parts as sub-properties of the field.
+      // $field_name may not be a reference field or the subsequent part may be
+      // a field property. In that case we should treat the rest of the parts as
+      // sub-properties of the field.
       if (empty($resource_types)) {
         return $this->constructInternalPath($reference_breadcrumbs, $parts);
       }
@@ -174,7 +194,7 @@ class FieldResolver {
     // This rebuilds the path from the real, internal field names that have
     // been traversed so far. It joins them with the "entity" keyword as
     // required by the entity query system.
-    $entity_path = implode('.entity.', $references);
+    $entity_path = implode('.', $references);
 
     // Reconstruct the full path to the final reference field.
     return (empty($field_path)) ? $entity_path : $entity_path . '.' . $field_path;
@@ -320,4 +340,49 @@ class FieldResolver {
     return array_keys($this->entityTypeBundleInfo->getBundleInfo($entity_type_id));
   }
 
+  /**
+   * Determines if a path part targets a field property, not a subsequent field.
+   *
+   * @param string $part
+   *   The path part.
+   * @param \Drupal\Core\TypedData\ComplexDataDefinitionInterface[] $candidate_definitions
+   *   A list of targeted field item definitions which are specified by the
+   *   path.
+   *
+   * @return bool
+   *   TRUE if the part is a property of one of the candidate definitions, FALSE
+   *   otherwise.
+   */
+  protected static function isCandidateDefinitionProperty($part, $candidate_definitions) {
+    foreach ($candidate_definitions as $definition) {
+      if ($definition->getPropertyDefinition($part)) {
+        return TRUE;
+      }
+    }
+    return FALSE;
+  }
+
+  /**
+   * Determines if a path part targets a reference property.
+   *
+   * @param string $part
+   *   The path part.
+   * @param \Drupal\Core\TypedData\ComplexDataDefinitionInterface[] $candidate_definitions
+   *   A list of targeted field item definitions which are specified by the
+   *   path.
+   *
+   * @return bool
+   *   TRUE if the part is a property of one of the candidate definitions, FALSE
+   *   otherwise.
+   */
+  protected static function isReferenceProperty($part, $candidate_definitions) {
+    foreach ($candidate_definitions as $definition) {
+      $property = $definition->getPropertyDefinition($part);
+      if ($property && $property instanceof DataReferenceDefinitionInterface) {
+        return TRUE;
+      }
+    }
+    return FALSE;
+  }
+
 }
diff --git a/tests/src/Kernel/Context/FieldResolverTest.php b/tests/src/Kernel/Context/FieldResolverTest.php
index 26a6796..941949f 100644
--- a/tests/src/Kernel/Context/FieldResolverTest.php
+++ b/tests/src/Kernel/Context/FieldResolverTest.php
@@ -75,6 +75,11 @@ class FieldResolverTest extends JsonapiKernelTestBase {
    */
   public function resolveInternalProvider() {
     return [
+      // Entity reference properties should not be expanded and reference
+      // properties should be honored.
+      ['field_test_ref1.target_id', 'field_test_ref1.target_id'],
+      ['field_test_ref1.entity.field_test_text.value', 'field_test_ref1.entity.field_test_text.value'],
+
       // Config entities.
       ['uuid', 'uuid', 'entity_test_bundle', 'entity_test_bundle'],
       ['type.entity.uuid', 'type.uuid'],
