Appearance
Basic Configuration
Configure Search with Elastic plugin settings.
Quick Start Configuration
Create a config/search-with-elastic.php file with recommended security settings:
php
<?php
return [
// Elasticsearch connection
'elasticsearchEndpoint' => getenv('ELASTICSEARCH_ENDPOINT'),
'isAuthEnabled' => true,
// Authentication credentials
'username' => getenv('ELASTICSEARCH_USERNAME'),
'password' => getenv('ELASTICSEARCH_PASSWORD'),
// Rate limiting (recommended)
'rateLimitingEnabled' => true,
'rateLimitRequestsPerMinute' => 60,
'rateLimitBurstSize' => 10,
// Index settings
'indexPrefix' => 'craft-',
'enableFrontendFetching' => true,
];php
<?php
return [
// Basic connection (development only)
'elasticsearchEndpoint' => 'localhost:9200',
'isAuthEnabled' => false,
// Minimal settings
'indexPrefix' => 'craft-',
'fallbackIndexName' => 'elements',
];yaml
version: '3.8'
services:
elasticsearch:
image: elasticsearch:8.11.0
environment:
- discovery.type=single-node
- xpack.security.enabled=false
ports:
- "9200:9200"
volumes:
- elasticsearch_data:/usr/share/elasticsearch/data
volumes:
elasticsearch_data:bash
# Basic environment variables
ELASTICSEARCH_ENDPOINT=elasticsearch:9200
ELASTICSEARCH_AUTH_ENABLED=falseConnection settings
Configure how the plugin connects to your Elasticsearch instance.
Elasticsearch endpoint
The elasticsearchEndpoint setting defines where your Elasticsearch server runs. It supports both traditional hostname:port format and full URLs with protocols:
php
// Local development (hostname:port format)
'elasticsearchEndpoint' => 'localhost:9200',
// Docker container (hostname:port format)
'elasticsearchEndpoint' => 'elasticsearch:9200',
// Full URL with protocol (recommended for remote servers)
'elasticsearchEndpoint' => 'https://my-elasticsearch.example.com:9200',
// Using environment variables (recommended for production)
'elasticsearchEndpoint' => '$ELASTICSEARCH_ENDPOINT',Protocol Handling
- If no protocol is specified in
hostname:portformat, the plugin will use HTTP by default - Full URLs with
https://will use HTTPS - Environment variables are automatically parsed using Craft's
App::parseEnv()
Authentication
Configure authentication for your Elasticsearch instance:
php
// Enable authentication
'isAuthEnabled' => true,
'username' => getenv('ELASTICSEARCH_USERNAME'),
'password' => getenv('ELASTICSEARCH_PASSWORD'),Rate Limiting
Protect against search abuse with configurable rate limits:
php
// Enable rate limiting
'rateLimitingEnabled' => true,
// Requests allowed per minute
'rateLimitRequestsPerMinute' => 60,
// Burst size for sudden traffic
'rateLimitBurstSize' => 10,
// Tracking method: 'ip' or 'user'
'rateLimitTrackingMethod' => 'ip',Rate Limiting in Templates
twig
{# Check rate limit status #}
{% set rateLimit = craft.searchWithElastic.getRateLimitStatus() %}
{% if rateLimit.enabled %}
<div class="rate-info">
Searches remaining: {{ rateLimit.remaining }} / {{ rateLimit.limit }}
</div>
{% endif %}Security Configuration
Configure security settings for the plugin.
Rate limiting
Prevent abuse and DoS attacks on your search endpoints:
php
// Enable rate limiting
'rateLimitingEnabled' => true,
// Requests allowed per minute (default: 60)
'rateLimitRequestsPerMinute' => 60,
// Extra burst capacity (default: 10)
'rateLimitBurstSize' => 10,
// Track by IP address or user ID
'rateLimitTrackingMethod' => 'ip', // 'ip' or 'user'
// Exempt trusted IPs
'rateLimitExemptIps' => [
'127.0.0.1',
'::1',
'192.168.1.0/24',
'$TRUSTED_IP_ADDRESS',
],Configuration examples
php
// Strict limits for public websites
'rateLimitingEnabled' => true,
'rateLimitRequestsPerMinute' => 30,
'rateLimitBurstSize' => 5,
'rateLimitTrackingMethod' => 'ip',php
// More lenient for logged-in users
'rateLimitingEnabled' => true,
'rateLimitRequestsPerMinute' => 120,
'rateLimitBurstSize' => 20,
'rateLimitTrackingMethod' => 'user',php
// Disabled for local development
'rateLimitingEnabled' => false,php
// Exempt internal network from limits
'rateLimitingEnabled' => true,
'rateLimitRequestsPerMinute' => 60,
'rateLimitExemptIps' => [
'10.0.0.0/8',
'172.16.0.0/12',
'192.168.0.0/16',
],Secure credentials
Best practices for managing Elasticsearch credentials:
php
// RECOMMENDED: Use environment variables
return [
'elasticsearchEndpoint' => '$ELASTICSEARCH_ENDPOINT',
'isAuthEnabled' => true,
'username' => '$ELASTICSEARCH_USERNAME',
'password' => '$ELASTICSEARCH_PASSWORD',
];Set environment variables in your .env file:
bash
ELASTICSEARCH_ENDPOINT="https://secure-es.example.com:9200"
ELASTICSEARCH_USERNAME="search_user"
ELASTICSEARCH_PASSWORD="secure_password_here"Production security
- Always use HTTPS in production
- Create read-only Elasticsearch users for search operations
- Use strong, unique passwords
- Rotate credentials regularly
- Never expose Elasticsearch directly to the internet
Index configuration
Control how the plugin creates and names Elasticsearch indexes.
Index naming structure
The plugin creates indexes using this pattern: {prefix}{indexName}_{siteId}
php
// Results in indexes like: craft-elements_1, craft-elements_2
'indexPrefix' => 'craft-',
'fallbackIndexName' => 'elements',
// Custom prefix for multiple Craft instances
'indexPrefix' => 'mysite-',
'fallbackIndexName' => 'content',
// Results in: mysite-content_1, mysite-content_2
// No prefix
'indexPrefix' => '',
'fallbackIndexName' => 'elements',
// Results in: elements_1, elements_2Element-specific indexes
Override index names for specific element types:
php
'elementTypeIndexNames' => [
'craft\\elements\\Entry' => 'entries', // craft-entries_1
'craft\\elements\\Asset' => 'assets', // craft-assets_1
'craft\\elements\\Category' => 'categories', // craft-categories_1
'craft\\commerce\\elements\\Product' => 'products', // craft-products_1
],Leave empty to use the fallback name:
php
'elementTypeIndexNames' => [
'craft\\elements\\Entry' => '', // Uses fallback: craft-elements_1
'craft\\elements\\Asset' => '', // Uses fallback: craft-elements_1
],Content indexing
Configure what content gets indexed and how it's processed.
Element types and statuses
Choose which element statuses to include in your search index:
php
// Include pending and live entries
'indexableEntryStatuses' => ['pending', 'live'],
// Only live entries
'indexableEntryStatuses' => ['live'],
// Include expired entries for search history
'indexableEntryStatuses' => ['pending', 'live', 'expired'],php
// Only enabled categories
'indexableCategoryStatuses' => ['enabled'],
// Include disabled categories
'indexableCategoryStatuses' => ['enabled', 'disabled'],php
// Pending and live products
'indexableProductStatuses' => ['pending', 'live'],
// Only live products
'indexableProductStatuses' => ['live'],Asset indexing
Control which asset types get indexed:
php
// Only PDF files
'assetKinds' => ['pdf'],
// Text-based assets
'assetKinds' => ['pdf', 'text', 'html', 'json', 'xml'],
// Document formats
'assetKinds' => ['pdf', 'word', 'excel', 'powerpoint'],
// All asset types (metadata only for non-text formats)
'assetKinds' => ['pdf', 'text', 'html', 'json', 'xml', 'word', 'excel', 'powerpoint', 'image', 'video', 'audio'],Available asset kinds:
pdf,word,excel,powerpoint- Documentstext,html,json,xml,javascript,php- Text filesimage,video,audio- Media files (metadata only)compressed,flash,illustrator,photoshop- Other formats
Frontend content fetching
The plugin can fetch rendered HTML content from your site's frontend URLs to include in the search index.
Basic frontend fetching
php
// Enable frontend content fetching (default)
'enableFrontendFetching' => true,
// Disable to index only element metadata
'enableFrontendFetching' => false,
// Index elements without URLs using their metadata
'indexElementsWithoutUrls' => true,Asset frontend fetching
Configure which asset types should have their content fetched from frontend URLs:
php
// No frontend fetching for assets (default)
'frontendFetchingAssetKinds' => [],
// Fetch content for text-based assets
'frontendFetchingAssetKinds' => ['text', 'html', 'json', 'xml'],
// Include JavaScript and PHP files
'frontendFetchingAssetKinds' => ['text', 'html', 'json', 'xml', 'javascript', 'php'],Exclusions
Exclude specific content types from indexing entirely.
Exclude element types
php
// Exclude specific entry types by handle
'excludedEntryTypes' => ['internalPages', 'adminNotes'],
// Exclude asset volumes by handle
'excludedAssetVolumes' => ['privateFiles', 'adminAssets'],
// Exclude category groups by handle
'excludedCategoryGroups' => ['internalCategories'],
// Commerce exclusions
'excludedProductTypes' => ['internalProducts'],
'excludedDigitalProductTypes' => ['adminOnly'],Exclude from frontend fetching
Skip frontend content fetching for specific element types while still indexing their metadata:
php
'excludedFrontendFetchingEntryTypes' => ['news', 'internalPages'],
'excludedFrontendFetchingAssetVolumes' => ['privateFiles'],
'excludedFrontendFetchingCategoryGroups' => ['internalCategories'],
'excludedFrontendFetchingProductTypes' => ['internalProducts'],
'excludedFrontendFetchingDigitalProductTypes' => ['adminOnly'],Search result highlighting
Configure how search terms are highlighted in results:
php
'highlight' => [
'pre_tags' => '<mark>',
'post_tags' => '</mark>',
],php
'highlight' => [
'pre_tags' => '<span class="highlight">',
'post_tags' => '</span>',
],php
'highlight' => [
'pre_tags' => '',
'post_tags' => '',
],Testing your configuration
After setting up your configuration:
- Test the connection: Go to Settings → Search with Elastic in your Craft control panel
- Reindex content: Use the utility or console command:bash
php craft search-with-elastic/index/reindex-all - Verify indexes: Check that indexes were created in Elasticsearch:bash
curl http://localhost:9200/_cat/indices
Next steps
- Environment-specific configuration for production deployments
- Index settings for performance optimization
- Multi-site configuration for complex setups