Views Search API: Wrong language used

Created on 3 June 2025, 5 days ago

Problem/Motivation

When using a Search API based view the translation management seems to go haywire as in; the content is always returned in the default language.

Steps to reproduce

  1. Have a multilingual Drupal setup with path prefixes
  2. Create a search index that indexes nodes with translations
  3. Create a Search API view that uses the index and Format Show: Rendered entity
  4. Create a Content view that directly returns the nodes with Format Show: Content
  5. Expose the two views in Graphql - assumed endpoint /graphql/general

Run a query like:

query ViewsLanguageHandling {
  searchApiView: entityById(entityType: VIEW, id: "testSearchApiView") {
    ... on View {
      executable(displayId: "default") {
        ... on ViewTestSearchApiViewDefault {
          execute(
            limit: 3
          ) {
            rows {
              ... on NodeEvent {
                titleRawField {
                  first {
                    value
                  }
                }
              }
            }
          }
        }
      }
    }
  }
  contentView: entityById(entityType: VIEW, id: "testContentView") {
    id
    ... on View {
      executable(displayId: "default") {
        ... on ViewTestContentViewDefault {
          execute(
            limit: 3
          ) {
            rows {
              ... on NodeEvent {
                titleRawField {
                  first {
                    value
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

Run the query on a non default language e.g. /de/graphql/general.
The results of the two views queries will differ - the Search API one will display the content in the default language while the Content view will show the proper translation.

Proposed resolution

This seems to be cause by \Drupal\graphql_core_schema\Plugin\GraphQL\DataProducer\ViewExecutor::getEntityTranslationRenderer()
There the renderer for the rows is determined under the implicit assumption that all handlers will use the approach from \Drupal\views\Entity\Render\EntityTranslationRenderTrait.
However, Search API uses an entirely different approach for that - in fact the rows / entities seem to already have the appropriate active language set ahead of time.

For lack of a better idea I think we could introduce a type check for SearchApi to bypass the call to getEntityTranslationByRelationship() in the resolver in \Drupal\graphql_core_schema\Plugin\GraphQL\DataProducer\ViewExecutor.

The other approach would be to add the type check in \Drupal\graphql_core_schema\Plugin\GraphQL\DataProducer\ViewExecutor::getEntityTranslationRenderer() and use Search APIs \Drupal\search_api\Plugin\views\EntityTranslationRenderer() as renderer.
This would allow to keep the whole getEntityTranslationByRelationship() handling in place.

Remaining tasks

  1. Write code
  2. Write tests?
  3. Reviews

User interface changes

None

API changes

None

Data model changes

None

🐛 Bug report
Status

Active

Version

1.0

Component

Code

Created by

🇚🇭Switzerland das-peter

Live updates comments and jobs are added and updated live.
  • views

    Involves, uses, or integrates with views. In Drupal 8 core, use the “VDC” tag instead.

Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @das-peter
  • 🇚🇭Switzerland das-peter

    I've pushed a modification based on the first proposed solution:

            // The search api backend uses its own language management. So only run
            // translation handling if this isn't a search api backend view.
            $row_entity = $row->_entity;
            if (!($this->view->getQuery() instanceof SearchApiQuery)) {
              $row_entity = $self->getEntityTranslationByRelationship($row->_entity, $row);
            }
    

    I'm not overly a fan of the readability of this because of the inverted condition - but this way getEntityTranslationByRelationship() is only run if necessary and no else condition is needed.

  • Pipeline finished with Success
    5 days ago
    Total: 237s
    #513080
  • 🇚🇭Switzerland das-peter
Production build 0.71.5 2024