diff --git a/Classes/Hooks/DataHandler.php b/Classes/Hooks/DataHandler.php
new file mode 100644
index 0000000..596b961
--- /dev/null
+++ b/Classes/Hooks/DataHandler.php
@@ -0,0 +1,63 @@
+
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+use TYPO3\CMS\Core\DataHandling\DataHandler as Typo3DataHandler;
+use TYPO3\CMS\Core\Utility\ArrayUtility;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Core\Utility\StringUtility;
+
+class DataHandler
+{
+ public function processCmdmap_beforeStart(Typo3DataHandler $dataHandler): void
+ {
+ $this->preventCopyOfTrackingTables($dataHandler);
+ }
+
+ public static function register(): void
+ {
+ ArrayUtility::mergeRecursiveWithOverrule($GLOBALS['TYPO3_CONF_VARS'], [
+ 'SC_OPTIONS' => [
+ 't3lib/class.t3lib_tcemain.php' => [
+ 'processCmdmapClass' => [
+ 'tracking' => self::class,
+ ],
+ ],
+ ],
+ ]);
+ }
+
+ private function preventCopyOfTrackingTables(Typo3DataHandler $dataHandler): void
+ {
+ $copyWhichTables = $dataHandler->compileAdminTables();
+
+ if ($dataHandler->copyWhichTables !== '*') {
+ $copyWhichTables = GeneralUtility::trimExplode(',', $dataHandler->copyWhichTables, true);
+ }
+
+ $copyWhichTables = array_filter($copyWhichTables, function (string $tableName) {
+ return StringUtility::beginsWith($tableName, 'tx_tracking_') === false;
+ });
+
+ $dataHandler->copyWhichTables = implode(',', $copyWhichTables);
+ }
+}
diff --git a/Tests/Functional/ExpectedResults/Typo3FeaturesTest/CopyPasteContainingRecords.csv b/Tests/Functional/ExpectedResults/Typo3FeaturesTest/CopyPasteContainingRecords.csv
new file mode 100644
index 0000000..83eb8e1
--- /dev/null
+++ b/Tests/Functional/ExpectedResults/Typo3FeaturesTest/CopyPasteContainingRecords.csv
@@ -0,0 +1,10 @@
+pages
+,"uid","pid"
+,1,0
+,2,1
+tx_tracking_pageview
+,"uid","pid"
+,1,1
+tx_tracking_recordview
+,"uid","pid"
+,1,1
diff --git a/Tests/Functional/Fixtures/Typo3FeaturesTest/PageWithRecords.xml b/Tests/Functional/Fixtures/Typo3FeaturesTest/PageWithRecords.xml
new file mode 100644
index 0000000..6167f58
--- /dev/null
+++ b/Tests/Functional/Fixtures/Typo3FeaturesTest/PageWithRecords.xml
@@ -0,0 +1,20 @@
+
+
+
+ 0
+ 1
+
+
+
+ 1
+ 1
+ https://example.com/path
+ Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36
+
+
+
+ 1
+ 1
+ https://example.com/path
+
+
diff --git a/Tests/Functional/Typo3FeaturesTest.php b/Tests/Functional/Typo3FeaturesTest.php
new file mode 100644
index 0000000..ab30ae9
--- /dev/null
+++ b/Tests/Functional/Typo3FeaturesTest.php
@@ -0,0 +1,91 @@
+
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+use DanielSiepmann\Tracking\Functional\CopyingPageWithRecordsWorks;
+use TYPO3\CMS\Core\DataHandling\DataHandler;
+use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
+use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase as TestCase;
+
+/**
+ * @covers \DanielSiepmann\Tracking\Functional\CopyingPageWithRecordsWorks
+ * @testdox This extension works with TYPO3 feature:
+ */
+class Typo3FeaturesTest extends TestCase
+{
+ protected $testExtensionsToLoad = [
+ 'typo3conf/ext/tracking',
+ ];
+
+ /**
+ * @test
+ * @testdox Copy pages. Tracking records will not be copied.
+ */
+ public function copyContainingRecords(): void
+ {
+ $this->importDataSet('EXT:tracking/Tests/Functional/Fixtures/Typo3FeaturesTest/PageWithRecords.xml');
+ $this->setUpBackendUserFromFixture(1);
+ $GLOBALS['LANG'] = $this->getContainer()->get(LanguageServiceFactory::class)->create('default');
+
+ $dataHandler = new DataHandler();
+ $dataHandler->start([], [
+ 'pages' => [
+ 1 => [
+ 'copy' => 1,
+ ],
+ ],
+ ]);
+ $dataHandler->process_cmdmap();
+
+ self::assertCount(0, $dataHandler->errorLog, 'Failed with errors: ' . implode(PHP_EOL, $dataHandler->errorLog));
+ $this->assertCSVDataSet(
+ 'EXT:tracking/Tests/Functional/ExpectedResults/Typo3FeaturesTest/CopyPasteContainingRecords.csv'
+ );
+ }
+
+ /**
+ * @test
+ * @testdox Copy individual tables, but always exclude tracking tables.
+ */
+ public function copyCustomTablesViaDataHandler(): void
+ {
+ $this->importDataSet('EXT:tracking/Tests/Functional/Fixtures/Typo3FeaturesTest/PageWithRecords.xml');
+ $this->setUpBackendUserFromFixture(1);
+ $GLOBALS['LANG'] = $this->getContainer()->get(LanguageServiceFactory::class)->create('default');
+
+ $dataHandler = new DataHandler();
+ $dataHandler->copyWhichTables = 'pages,tx_tracking_pageview,tx_tracking_recordview';
+ $dataHandler->start([], [
+ 'pages' => [
+ 1 => [
+ 'copy' => 1,
+ ],
+ ],
+ ]);
+ $dataHandler->process_cmdmap();
+
+ self::assertCount(0, $dataHandler->errorLog, 'Failed with errors: ' . implode(PHP_EOL, $dataHandler->errorLog));
+ $this->assertCSVDataSet(
+ 'EXT:tracking/Tests/Functional/ExpectedResults/Typo3FeaturesTest/CopyPasteContainingRecords.csv'
+ );
+ }
+}
diff --git a/ext_localconf.php b/ext_localconf.php
new file mode 100644
index 0000000..df41943
--- /dev/null
+++ b/ext_localconf.php
@@ -0,0 +1,3 @@
+
/Tests/*
+
+ /Classes/Hooks/DataHandler.php
+