diff --git a/search_api.module b/search_api.module
index 52e740ea..ab9cb01a 100644
--- a/search_api.module
+++ b/search_api.module
@@ -191,6 +191,13 @@ function search_api_config_import_steps_alter(&$sync_steps, ConfigImporter $conf
  * By setting the $entity->search_api_skip_tracking property to a true-like
  * value before this hook is invoked, you can prevent this behavior and make the
  * Search API ignore this new entity.
+ *
+ * Note that this function implements tracking only on behalf of the "Content
+ * Entity" datasource defined in this module, not for entity-based datasources
+ * in general. Datasources defined by other modules still have to implement
+ * their own mechanism for tracking new/updated/deleted entities.
+ *
+ * @see \Drupal\search_api\Plugin\search_api\datasource\ContentEntity
  */
 function search_api_entity_insert(EntityInterface $entity) {
   // Check if the entity is a content entity.
@@ -225,6 +232,13 @@ function search_api_entity_insert(EntityInterface $entity) {
  * By setting the $entity->search_api_skip_tracking property to a true-like
  * value before this hook is invoked, you can prevent this behavior and make the
  * Search API ignore this update.
+ *
+ * Note that this function implements tracking only on behalf of the "Content
+ * Entity" datasource defined in this module, not for entity-based datasources
+ * in general. Datasources defined by other modules still have to implement
+ * their own mechanism for tracking new/updated/deleted entities.
+ *
+ * @see \Drupal\search_api\Plugin\search_api\datasource\ContentEntity
  */
 function search_api_entity_update(EntityInterface $entity) {
   // Check if the entity is a content entity.
@@ -286,6 +300,13 @@ function search_api_entity_update(EntityInterface $entity) {
  * Search API ignore this deletion. (Note that this might lead to stale data in
  * the tracking table or on the server, since the item will not removed from
  * there (if it has been added before).)
+ *
+ * Note that this function implements tracking only on behalf of the "Content
+ * Entity" datasource defined in this module, not for entity-based datasources
+ * in general. Datasources defined by other modules still have to implement
+ * their own mechanism for tracking new/updated/deleted entities.
+ *
+ * @see \Drupal\search_api\Plugin\search_api\datasource\ContentEntity
  */
 function search_api_entity_delete(EntityInterface $entity) {
   // Check if the entity is a content entity.
diff --git a/tests/src/Kernel/LanguageKernelTest.php b/tests/src/Kernel/LanguageKernelTest.php
index ee3bdc2e..2d315a54 100644
--- a/tests/src/Kernel/LanguageKernelTest.php
+++ b/tests/src/Kernel/LanguageKernelTest.php
@@ -10,6 +10,7 @@
 use Drupal\language\Entity\ConfigurableLanguage;
 use Drupal\search_api\Entity\Index;
 use Drupal\search_api\Entity\Server;
+use Drupal\search_api\Utility\Utility;
 
 /**
  * Tests translation handling of the content entity datasource.
@@ -288,4 +289,75 @@ public function testItemTranslations() {
     $this->assertEquals(3, $this->index->getTrackerInstance()->getIndexedItemsCount(), 'Three items are indexed.');
   }
 
+  /**
+   * Tests tracking when the datasource has only specific languages enabled.
+   */
+  public function testDatasourceLanguagesSetting() {
+    $datasource_id = 'entity:' . $this->testEntityTypeId;
+    $datasource = $this->index->getDatasource($datasource_id);
+    $datasource->setConfiguration([
+      'languages' => [
+        'default' => FALSE,
+        'selected' => [$this->langcodes[0], $this->langcodes[2]],
+      ],
+    ]);
+    $this->index->save();
+
+    // Create new entities with our three custom languages and one with the
+    // default language (English).
+    /** @var \Drupal\entity_test\Entity\EntityTestMulRevChanged[] $entities */
+    $entities = [];
+    $uid = $this->container->get('current_user')->id();
+    foreach ([0, 1, 2, 3] as $i) {
+      $entity = EntityTestMulRevChanged::create([
+        'id' => $i + 1,
+        'name' => 'test 1',
+        'user_id' => $uid,
+      ]);
+      if (!empty($this->langcodes[$i])) {
+        $entity->set('langcode', $this->langcodes[$i]);
+      }
+      $entity->save();
+      $entities[$i] = $entity;
+    }
+
+    // Only the ones with languages "l0" and "l2" should have been tracked.
+    $tracker = $this->index->getTrackerInstance();
+    $this->assertEquals(2, $tracker->getTotalItemsCount());
+    $expected = [
+      Utility::createCombinedId($datasource_id, "1:{$this->langcodes[0]}"),
+      Utility::createCombinedId($datasource_id, "3:{$this->langcodes[2]}"),
+    ];
+    $actual = $tracker->getRemainingItems();
+    sort($actual);
+    $this->assertEquals($expected, $actual);
+
+    // Add a translation for a disabled language. It should not be tracked.
+    $entities[0]->addTranslation($this->langcodes[1])->save();
+    $this->assertEquals(2, $tracker->getTotalItemsCount());
+    $actual = $tracker->getRemainingItems();
+    sort($actual);
+    $this->assertEquals($expected, $actual);
+
+    // Add a translation for an enabled language. It should be tracked.
+    $langcode = $this->langcodes[0];
+    $entities[1]->addTranslation($langcode)->save();
+    $this->assertEquals(3, $tracker->getTotalItemsCount());
+    $expected_1 = $expected;
+    $expected_1[] = Utility::createCombinedId($datasource_id, "2:$langcode");
+    sort($expected_1);
+    $actual = $tracker->getRemainingItems();
+    sort($actual);
+    $this->assertEquals($expected_1, $actual);
+
+    // Remove that translation again and verify that it's also deleted from the
+    // tracker.
+    $entities[1]->removeTranslation($langcode);
+    $entities[1]->save();
+    $this->assertEquals(2, $tracker->getTotalItemsCount());
+    $actual = $tracker->getRemainingItems();
+    sort($actual);
+    $this->assertEquals($expected, $actual);
+  }
+
 }
