Skip to main content Inicio Creadores jeremylongshore tons-of-skills-marketplace 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".
Ir a la instalación Skills Marketplace Descubre y explora habilidades de IA creadas por la comunidad.
Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
Copiar promptMostrar detalles del prompt Un comando directo omite el prompt de revisión. Revisa el origen antes de ejecutarlo.
npx skills add https://github.com/jeremylongshore/tons-of-skills-marketplace --skill algolia-multi-env-setupEl comando permanece en una sola línea. Desplázate horizontalmente para revisarlo antes de copiarlo.
¿Prefieres una copia local? Descarga los archivos que SkillsMP tiene disponibles ahora.
Descargar Zip Descargando... Más de este repositorio langchain-deploy-integration Deploy a LangChain 1.0 / LangGraph 1.0 app to Cloud Run, Vercel, or LangServe correctly — with timeouts sized for chain length, cold-start mitigation, SSE anti-buffering headers, and Secret Manager over .env. Use when prepping a first production deploy, debugging a stream that hangs behind a proxy, or diagnosing p99 latency spikes. Trigger with "langchain deploy", "langchain cloud run", "langchain vercel python", "langchain langserve", or "langchain docker".
langchain-langgraph-agents Build a correct LangGraph 1.0 ReAct agent with create_react_agent — typed tools, error propagation, recursion caps, and stop conditions that actually stop. Use when writing a first tool-calling agent, migrating from AgentExecutor or initialize_agent, or diagnosing an agent that loops on vague prompts. Trigger with "langgraph agent", "create_react_agent", "langgraph tool calling", "AgentExecutor migration", or "agent loop cost".
langchain-langgraph-human-in-loop Build LangGraph 1.0 human-in-the-loop approval flows with interrupt_before /
interrupt_after and Command(resume=...) — JSON-serializable state, clean
resume semantics, and UI wiring for approval decisions. Use when adding an
approval gate before an expensive tool call, wiring a Slack/web UI for agent
approvals, or debugging a graph that crashes on interrupt.
Trigger with "langgraph human in loop", "langgraph interrupt_before",
"langgraph approval flow", "Command resume", "langgraph HITL".
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.7.0 license MIT author Jeremy Longshore <jeremy@intentsolutions.io> tags ["saas","search","algolia"] compatibility Designed for 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.
Prerequisites
Separate environment names or application credentials and a clear production promotion policy.
CI secrets scoped to the environment that performs indexing.
A naming convention that prevents a staging job from writing to the production index.
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
Examples
The index-prefix and configuration examples below demonstrate environment isolation and controlled promotion. Keep the same convention in local tooling, CI, and runtime configuration to avoid cross-environment writes.
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 ( ): {
env = (process. . || ) ;
{
: process. . !,
: process. . !,
: process. . !,
: env,
};
}
( ): {
{ environment } = ();
(environment === ) base;
;
}
: | = ;
( ): {
(!_client) {
config = ();
_client = (config. , config. );
}
_client;
}
getConfig
AlgoliaConfig
const
env
NODE_ENV
'development'
as
Environment
return
appId
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 );
Output Each environment resolves to the intended index and credentials, with promotion and rollback paths that do not expose production keys or overwrite production data from staging.
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.