Skip to main content ホーム クリエイター comeonoliver skillshub algolia-multi-env-setup
algolia-multi-env-setup Configure Algolia across dev/staging/production: index prefixing, per-environment
API keys, settings-as-code, and environment isolation guards.
Trigger: "algolia environments", "algolia staging", "algolia dev prod",
"algolia environment setup", "algolia config by env".
インストールへ移動 Skills Marketplace コミュニティが作成したAIスキルを発見・探索
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
直接コマンドでは確認用 Prompt が省略されます。実行前にソースを確認してください。
npx skills add https://github.com/ComeOnOliver/skillshub --skill algolia-multi-env-setupコマンドは1行のまま表示されます。コピー前に横へスクロールして全体を確認してください。
ローカルで確認しますか?SkillsMP が現在取得できるファイルをダウンロードできます。
Zipをダウンロード ダウンロード中... このリポジトリの他の Skills Review product and feature risk before an AI coding agent starts implementation.
Use Xquik for X data and confirmation-gated X actions: tweet search, user lookup, follower export, media download, monitors, webhooks, MCP, and SDK workflows.
Canton Network open-source ecosystem guide covering DAML SDK, Canton runtime, and Splice applications. Use when working with Canton Network, DAML smart contracts, or building decentralized applications.
name algolia-multi-env-setup description Configure Algolia across dev/staging/production: index prefixing, per-environment
API keys, settings-as-code, and environment isolation guards.
Trigger: "algolia environments", "algolia staging", "algolia dev prod",
"algolia environment setup", "algolia config by env".
allowed-tools Read, Write, Edit, Bash(npm:*), Bash(gcloud:*), Bash(vault:*) version 1.0.0 license MIT author Jeremy Longshore <jeremy@intentsolutions.io> tags ["saas","search","algolia"] compatible-with claude-code
Algolia Multi-Environment Setup
Overview
Algolia doesn't have built-in environment separation. You either use separate Algolia applications (strongest isolation) or index prefixing within one application (simpler). This skill covers both approaches.
Environment Strategies
Strategy Isolation Cost Complexity Index prefixing Shared app, prefixed names Lowest Low Separate API keys Shared app, scoped keys Low Medium Separate applications Full isolation Highest High
Instructions
Step 1: Index Prefixing (Recommended for Most Teams)
import { algoliasearch, type Algoliasearch } from 'algoliasearch' ;
type Environment = 'development' | 'staging' | 'production' ;
interface AlgoliaConfig {
appId : string ;
apiKey : string ;
searchKey : string ;
environment : Environment ;
}
function getConfig ( ): AlgoliaConfig {
const env = (process.env .NODE_ENV || 'development' ) as Environment ;
return {
appId : process. . !,
: process. . !,
: process. . !,
: env,
};
}
( ): {
{ environment } = ();
(environment === ) base;
;
}
: | = ;
( ): {
(!_client) {
config = ();
_client = (config. , config. );
}
_client;
}
env
ALGOLIA_APP_ID
apiKey
env
ALGOLIA_ADMIN_KEY
searchKey
env
ALGOLIA_SEARCH_KEY
environment
export
function
indexName
base : string
string
const
getConfig
if
'production'
return
return
`${environment} _${base} `
let
_client
Algoliasearch
null
null
export
function
getClient
Algoliasearch
if
const
getConfig
algoliasearch
appId
apiKey
return
Step 2: Scoped API Keys Per Environment import { algoliasearch } from 'algoliasearch' ;
const adminClient = algoliasearch (process.env .ALGOLIA_APP_ID !, process.env .ALGOLIA_ADMIN_KEY !);
async function createEnvironmentKeys ( ) {
const { key : stagingKey } = await adminClient.addApiKey ({
apiKey : {
acl : ['search' , 'addObject' , 'deleteObject' , 'editSettings' , 'browse' ],
description : 'Staging environment — full access to staging indices only' ,
indexes : ['staging_*' ],
maxQueriesPerIPPerHour : 10000 ,
},
});
console .log (`Staging key: ${stagingKey} ` );
const { key : devKey } = await adminClient.addApiKey ({
apiKey : {
acl : ['search' , 'addObject' , 'deleteObject' , 'editSettings' , 'browse' ],
description : 'Development environment — full access to dev indices only' ,
indexes : ['development_*' ],
maxQueriesPerIPPerHour : 5000 ,
},
});
console .log (`Dev key: ${devKey} ` );
const { key : prodSearchKey } = await adminClient.addApiKey ({
apiKey : {
acl : ['search' ],
description : 'Production search — read only' ,
indexes : ['products' , 'articles' , 'faq' ],
maxQueriesPerIPPerHour : 50000 ,
maxHitsPerQuery : 100 ,
},
});
console .log (`Prod search key: ${prodSearchKey} ` );
}
Step 3: Environment Variables Per Platform
ALGOLIA_APP_ID=YourAppID
ALGOLIA_ADMIN_KEY=dev_scoped_key_here
ALGOLIA_SEARCH_KEY=dev_search_key_here
NODE_ENV=development
ALGOLIA_APP_ID=YourAppID
ALGOLIA_ADMIN_KEY=staging_scoped_key_here
ALGOLIA_SEARCH_KEY=staging_search_key_here
NODE_ENV=staging
Step 4: Settings-as-Code with Environment Overrides
import type { IndexSettings } from 'algoliasearch' ;
const baseSettings : IndexSettings = {
searchableAttributes : ['name' , 'brand' , 'category' , 'unordered(description)' ],
attributesForFaceting : ['searchable(brand)' , 'category' , 'filterOnly(price)' ],
customRanking : ['desc(review_count)' , 'desc(rating)' ],
};
const envOverrides : Partial <Record <string , Partial <IndexSettings >>> = {
development : {
replicas : [],
},
staging : {
replicas : ['virtual(staging_products_price_asc)' ],
},
production : {
replicas : [
'virtual(products_price_asc)' ,
'virtual(products_price_desc)' ,
'virtual(products_newest)' ,
],
},
};
export function getSettings (env : string ): IndexSettings {
return { ...baseSettings, ...envOverrides[env] };
}
Step 5: Environment Isolation Guard
export function guardEnvironment (operation : string , targetIndex : string ) {
const env = process.env .NODE_ENV || 'development' ;
if (env === 'production' ) {
if (targetIndex.startsWith ('development_' ) || targetIndex.startsWith ('staging_' )) {
throw new Error (`Blocked: ${operation} on ${targetIndex} from production` );
}
} else {
if (!targetIndex.startsWith (`${env} _` )) {
throw new Error (`Blocked: ${operation} on ${targetIndex} from ${env} . Use prefixed index.` );
}
}
}
async function deleteIndex (name : string ) {
guardEnvironment ('deleteIndex' , name);
await getClient ().deleteIndex ({ indexName : name });
}
Step 6: Seed Script Per Environment
import { getClient, indexName } from '../src/algolia/config' ;
import { getSettings } from '../config/algolia-settings' ;
async function seedEnvironment ( ) {
const env = process.env .NODE_ENV || 'development' ;
const client = getClient ();
const idx = indexName ('products' );
console .log (`Seeding ${env} environment → index: ${idx} ` );
await client.setSettings ({ indexName : idx, indexSettings : getSettings (env) });
if (env !== 'production' ) {
const testData = await import ('../fixtures/products.json' );
const { taskID } = await client.replaceAllObjects ({
indexName : idx,
objects : testData.default ,
});
await client.waitForTask ({ indexName : idx, taskID });
console .log (`Seeded ${testData.default .length} records` );
}
}
seedEnvironment ().catch (console .error );
Error Handling Issue Cause Solution Wrong index in production Missing prefix logic Use indexName() helper everywhere Staging data leaking to prod Shared API key Use scoped keys restricted to index patterns Settings drift between envs Manual dashboard changes Apply settings from code in CI Dev index polluting record count Old test indices Scheduled cleanup job for development_* indices
Resources
Next Steps For observability setup, see algolia-observability.