{"id":30228529,"url":"https://github.com/studioespresso/craft-scout","last_synced_at":"2025-08-14T19:55:17.483Z","repository":{"id":40521346,"uuid":"113917206","full_name":"studioespresso/craft-scout","owner":"studioespresso","description":"Craft Scout provides a simple solution for adding full-text search to your entries. Scout will automatically keep your search indexes in sync with your entries.","archived":false,"fork":false,"pushed_at":"2025-07-22T19:14:32.000Z","size":3493,"stargazers_count":81,"open_issues_count":17,"forks_count":54,"subscribers_count":5,"default_branch":"v5","last_synced_at":"2025-07-24T11:42:51.675Z","etag":null,"topics":["algolia","algolia-search","craft-plugin","craftcms"],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/studioespresso.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":["janhenckens"]}},"created_at":"2017-12-11T22:52:17.000Z","updated_at":"2025-06-10T18:58:53.000Z","dependencies_parsed_at":"2023-11-08T13:45:09.305Z","dependency_job_id":"98c763c1-68f3-4884-a5c1-5678e7c344bd","html_url":"https://github.com/studioespresso/craft-scout","commit_stats":{"total_commits":271,"total_committers":33,"mean_commits":8.212121212121213,"dds":0.5498154981549815,"last_synced_commit":"197aef6d96474afc8e5e4dcf0974726777f84995"},"previous_names":[],"tags_count":90,"template":false,"template_full_name":null,"purl":"pkg:github/studioespresso/craft-scout","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/studioespresso%2Fcraft-scout","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/studioespresso%2Fcraft-scout/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/studioespresso%2Fcraft-scout/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/studioespresso%2Fcraft-scout/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/studioespresso","download_url":"https://codeload.github.com/studioespresso/craft-scout/tar.gz/refs/heads/v5","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/studioespresso%2Fcraft-scout/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270475433,"owners_count":24590076,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-14T02:00:10.309Z","response_time":75,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["algolia","algolia-search","craft-plugin","craftcms"],"created_at":"2025-08-14T19:55:15.424Z","updated_at":"2025-08-14T19:55:17.431Z","avatar_url":"https://github.com/studioespresso.png","language":"PHP","funding_links":["https://github.com/sponsors/janhenckens"],"categories":[],"sub_categories":[],"readme":"# Scout for Craft CMS\n\nCraft Scout provides a simple solution for adding full-text search to your entries. Scout will automatically keep your search indices in sync with your entries.\n\n![Scout](https://www.studioespresso.co/assets/Scout-Github-Banner.png)\n\n## Requirements\n\nThis plugin requires Craft CMS 4.x or later and PHP 8.0.2 or later.\n\n## Installation\n\nOpen your terminal and go to your Craft project:\n\n```bash\n# go to the project directory\ncd /path/to/my-craft-project.dev\n\n# tell Composer to install the plugin\ncomposer require studioespresso/craft-scout\n\n# tell Craft to install the plugin\nphp craft plugin/install scout\n```\n\n## Setup\n\nTo define your indices, copy the [scout.php](config/scout.php) file to your `config` folder.\n\n```php\n\u003c?php\n\nreturn [\n    /*\n     * Scout listens to numerous Element events to keep them updated in\n     * their respective indices. You can disable these and update\n     * your indices manually using the commands.\n     */\n    'sync' =\u003e true,\n\n    /*\n     * \n     * @depcretio\n     * By default Scout handles all indexing in a queued job, you can disable\n     * this so the indices are updated as soon as the elements are updated\n     * \n     * Disabling the `queue` option will no longer be supported in the next version of Scout\n     * \n     */\n    'queue' =\u003e true,\n\n    /*\n     * The connection timeout (in seconds), increase this only if necessary\n     */\n    'connect_timeout' =\u003e 1,\n\n    /*\n     * The batch size Scout uses when importing a large amount of elements\n     */\n    'batch_size' =\u003e 1000,\n    \n    /*\n     * By default Scout will index elements related to the element being save (that are in the same index). \n     * Disabling this can improve performance on larger sites that have lots of relations.\n     */\n    'indexRelations' =\u003e true,\n    \n    /**\n     * The element types to look for when indexRelations is enabled.\n     * By default, all Craft elements are checked for relations.\n     * Use this to avoid unnecessary queries to Elements that aren't\n     * used by your indices or to check custom Elements that may be\n     * related to your indices\n     */\n    'relatedElementTypes' =\u003e [],\n\n    /*\n     * The Algolia Application ID, this id can be found in your Algolia Account\n     * https://www.algolia.com/api-keys. This id is used to update records.\n     */\n    'application_id' =\u003e '$ALGOLIA_APPLICATION_ID',\n\n    /*\n     * The Algolia Admin API key, this key can be found in your Algolia Account\n     * https://www.algolia.com/api-keys. This key is used to update records.\n     */\n    'admin_api_key'  =\u003e '$ALGOLIA_ADMIN_API_KEY',\n\n    /*\n     * The Algolia search API key, this key can be found in your Algolia Account\n     * https://www.algolia.com/api-keys. This search key is not used in Scout\n     * but can be used through the Scout variable in your template files.\n     */\n    'search_api_key' =\u003e '$ALGOLIA_SEARCH_API_KEY', //optional\n    \n    /*\n     * A collection of indices that Scout should sync to, these can be configured\n     * by using the \\rias\\scout\\ScoutIndex::create('IndexName') command. Each\n     * index should define an ElementType, criteria and a transformer.\n     */\n    'indices'       =\u003e [],\n];\n```\n\n### Example Index Configuration\n\n```php\n\u003c?php\n\nreturn [\n    'indices'       =\u003e [\n        \\rias\\scout\\ScoutIndex::create('Blog')\n            // Scout uses this by default, so this is optional\n            -\u003eelementType(\\craft\\elements\\Entry::class)\n            // If you don't define a siteId, the primary site is used\n            -\u003ecriteria(function (\\craft\\elements\\db\\EntryQuery $query) {\n                return $query-\u003esection('blog');\n            })\n            /*\n             * The element gets passed into the transform function, you can omit this\n             * and Scout will use the \\rias\\scout\\ElementTransformer class instead\n            */\n            -\u003etransformer(function (\\craft\\elements\\Entry $entry) {\n                return [\n                    'title' =\u003e $entry-\u003etitle,\n                    'body' =\u003e $entry-\u003ebody,\n                ];\n            })\n            /*\n             * You can use this to define index settings that get synced when you call\n             * the ./craft scout/settings/update console command. This way you can\n             * keep your index settings in source control. The IndexSettings\n             * object provides autocompletion for all Algolia's settings\n            */\n            -\u003eindexSettings(\n                \\rias\\scout\\IndexSettings::create()\n                    -\u003eminWordSizefor1Typo(4)\n            )\n    ],\n];\n```\n\n#### `-\u003eelementType(string $class)`\nThe element type that this index contains, by default Scout uses `craft\\elements\\Entry::class`\n\nCraft's default element type classes are:\n\n- `craft\\elements\\Asset`\n- `craft\\elements\\Entry`\n- `craft\\elements\\User`\n\n#### `-\u003ecriteria(callable $query)`\nThis function accepts an `ElementQuery` and should also return an `ElementQuery`\n\n```php\n-\u003ecriteria(function (ElementQuery $query) {\n    return $query-\u003esection('blog');\n});\n```\n\n#### `-\u003etransformer(callable|string|array|TransformerAbstract $transformer)`\nThe [transformer](http://fractal.thephpleague.com/transformers/) that should be used to define the data that should be sent to Algolia for each element. If you don’t set this, the default transformer will be used, which includes all of the element’s direct attribute values, but no custom field values.\n\n```php\n// Can be set to a function\n-\u003etransformer(function(craft\\elements\\Entry $entry) {\n    return [\n        'title' =\u003e $entry-\u003etitle,\n        'id' =\u003e $entry-\u003eid,\n        'url' =\u003e $entry-\u003eurl,\n    ];\n}),\n\n// Or a string/array that defines a Transformer class configuration\n-\u003etransformer('MyTransformerClassName'),\n\n// Or a Transformer class instance\n-\u003etransformer(new MyTransformerClassName()),\n\n```\nYour custom transformer class would look something like this:\n```php\n\u003c?php\n\nuse craft\\elements\\Entry;\nuse League\\Fractal\\TransformerAbstract;\n\nclass MyTransformerClassName extends TransformerAbstract\n{\n    public function transform(Entry $entry)\n    {\n        return [\n            // ...\n        ];\n    }\n}\n```\n\n#### `-\u003esplitElementsOn(array $keys)`\n[For long documents](https://www.algolia.com/doc/guides/sending-and-managing-data/prepare-your-data/how-to/indexing-long-documents/) it is advised to divide the element into multiple rows to keep each row within row data size. This can be done using `splitElementsOn()`.\n\u003e Make sure to return an array in your transformer for these keys.\n\n```php\n-\u003esplitElementsOn([\n    'summary',\n    'matrixFieldHandle'\n])\n```\n\n\u003e *Important* - `distinctID` (available after indexing) must be set up as an attribute for faceting for deletion of objects to work when using splitElementsOn.\n\n#### `-\u003eindexSettings(IndexSettings $settings)`\n\nYou can use this to define index settings that get synced when you call the `./craft scout/settings/update` console command. \nThis way you can keep your index settings in source control. \nThe IndexSettings object provides autocompletion for all Algolia's settings\n\n\u003e [!NOTE]  \n\u003e Note that settings are not synced automatically, but only when the `./craft scout/settings/update` console command is run.\n\n```php\n-\u003eindexSettings(\n    \\rias\\scout\\IndexSettings::create()\n        -\u003eminWordSizefor1Typo(4)\n)\n```\n\n### Replicas\n\nReplicas can be created with the `replicas` function on `IndexSettings`. To configure replicas, include them in the `indices` array and set their `replicaIndex` to `true` so that they are not included in any syncing operations.\n\nReplica indices can have their configuration updated using the `./craft scout/settings/update` console command.\n\n```php\n\u003c?php\n\nreturn [\n    'indices' =\u003e [\n        \\rias\\scout\\ScoutIndex::create('Products')\n            // ...\n            -\u003eindexSettings(\n                \\rias\\scout\\IndexSettings::create()\n                    -\u003eminWordSizefor1Typo(4)\n                    -\u003ereplicas(['virtual(Products_desc)'])\n            )\n    ],\n    [\n        \\rias\\scout\\ScoutIndex::create('Products_desc')\n            -\u003ereplicaIndex(true)\n            -\u003eindexSettings(IndexSettings::create()-\u003ecustomRanking(['desc(price)'])),\n    ],\n];\n```\n\n## Twig variables\nYou can access the Algolia settings set in your config file through the following Twig variables.\n\n```twig\n{{ craft.scout.pluginName }}\n{{ craft.scout.algoliaApplicationId }}\n{{ craft.scout.algoliaAdminApiKey }}\n{{ craft.scout.algoliaSearchApiKey }}\n```\n\n## Console commands\nScout provides two easy console commands for managing your indices.\n\n### Importing\nTo import one or all indices you can run the following console command\n\n```\n./craft scout/index/import \u003cindexName?\u003e\n```\n\nThe `indexName` argument is not required, all your mappings will be imported when you omit it.\n\n### Flushing/Clearing\nClearing an index is as easy as running a command in your console.\n\n```\n./craft scout/index/flush \u003cindexName?\u003e\n```\n\nAs with the import command, `indexName` is not required.\n\nWhen flushing, Scout will ask you to confirm that you really want to clear all the data in your index. You can bypass the confirmation by appending a `--force` flag.\n\n### Refreshing\nDoes a flush/clear first and then imports the index again.\n\n```\n./craft scout/index/refresh \u003cindexName?\u003e\n```\n\n## Skipping an Element\n\nYou can omit an element from being indexed by returning an **empty array** from the `transform` method:\n\n```php\nScoutIndex::create()\n    -\u003etransform(function (Entry $entry) {\n        // Check if entry is valid for indexing\n        $isValid = yourCustomValidation($entry);\n        \n        // If entry fails validation, return empty array\n        if (! $isValid) {\n            return [];\n        }\n    \n        // Return normal data attributes\n        return [\n            'name' =\u003e $entry-\u003etitle,\n            ...\n            'lorem' =\u003e $entry-\u003elorem,\n            'ipsum' =\u003e $entry-\u003eipsum,\n        ];\n    });\n```\n\n## Events\n\n### ShouldBeSearchableEvent\n\nThis event allows you to customize which elements or element types get checked on save (or more specifically, every time the `SearchableBehaviour` is triggered).\n\n```php \n\nuse rias\\scout\\behaviors\\SearchableBehavior;\nuse rias\\scout\\events\\ShouldBeSearchableEvent;\n\nEvent::on(\n    SearchableBehavior::class, \n    SearchableBehavior::EVENT_SHOULD_BE_SEARCHABLE, \n    function (ShouldBeSearchableEvent $event) {\n        $event-\u003eshouldBeSearchable = false;\n});\n```\n\nThe event has a properties: \n- $element (the element being saved)\n- $shouldBeSearchable (wether or not the element should be searchable, defaults to `true`)\n\nAn example use-case for this would be to check the type of the element that's being saved and settings `shouldBeSearchable` to `false` when it's a Matrix block.\n\n### AfterIndexImport\n\nThis event runs at the end of the `ImportIndex` job, when every item has been processed.\n\n```php \n\nuse rias\\scout\\events\\AfterIndexImport;\nuse rias\\scout\\jobs\\ImportIndex;\n\nEvent::on(\n    ImportIndex::class,\n    ImportIndex::EVENT_AFTER_INDEX_IMPORT,\n    function (AfterIndexImport $event) {\n        // Your code here\n    });\n```\n\nThe event has one property:\n- $indexName (the name of the index that just finished importing\n\nAn example use-case for this would be to keep a log or dateLastImported if you're running imports on a schedule.\n\n\n---\n\n## Upgrading from 1.x\n\nThe configuration has changed from how Scout v1 did its configuration. Please see the [setup](#setup) section below on how to configure Scout.\n\nThe following changes are the most notable:\n- The `mappings` configuration key has been changed to `indices` and there is a new way to configure the indices\n- The `criteria` is now a callable that returns an `ElementQuery`. Every Index should define a `siteId` in the criteria, otherwise the primary site is chosen.\n- New `queue` and `batch` options added to the settings\n- Old confuguration keys on the mappings have been replaced by functions on the `rias\\scout\\ScoutIndex` object.\n\n----\n\nBrought to you by [Studio Espresso](https://www.studioespresso.dev/) and [Rias](https://rias.be)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstudioespresso%2Fcraft-scout","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstudioespresso%2Fcraft-scout","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstudioespresso%2Fcraft-scout/lists"}