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