Prerequisites
Before you begin, ensure you have:- An EverShop project set up and running
- Node.js and npm installed
- Basic knowledge of JavaScript/TypeScript
- Familiarity with React (for UI components)
{
"name": "my-evershop-extension",
"version": "1.0.0",
"main": "index.js",
"type": "module",
"scripts": {
"tsc": "tsc"
},
"keywords": [],
"author": "",
"license": "ISC"
}
{
"compilerOptions": {
"target": "ES2020",
"module": "ES2020",
"moduleResolution": "node",
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"jsx": "react",
"declaration": true,
"declarationMap": true,
"sourceMap": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
mkdir -p src/api
mkdir -p src/pages/frontStore
mkdir -p src/pages/admin
mkdir -p src/subscribers
mkdir -p src/graphql/types
mkdir -p src/crons
mkdir -p dist
{
"system": {
"extensions": [
{
"name": "my-extension",
"resolve": "extensions/my-extension",
"enabled": true,
"priority": 10
}
]
}
}
name: Unique identifier for your extensionresolve: Path to extension directory (relative to project root)enabled: Set to true to enable the extensionpriority: Lower numbers load first (default: 10)import path from 'path';
import { registerJob } from '@evershop/evershop/lib/cronjob';
export default function () {
registerJob({
name: 'myCustomJob',
schedule: '0 0 * * *', // Runs daily at midnight
resolve: path.resolve(import.meta.dirname, 'crons', 'dailyJob.js'),
enabled: true
});
}
import { EventSubscriber } from '@evershop/evershop/lib/event/subscriber';
const logProduct: EventSubscriber<'product_created'> = async (data) => {
console.log('New product created:', {
id: data.product_id,
name: data.name,
sku: data.sku
});
// Add your custom logic here
// - Send notification
// - Update external system
// - Trigger workflow
};
export default logProduct;
import React from 'react';
export default function Banner() {
return (
<div className="bg-blue-600 text-white py-3 px-4">
<div className="container mx-auto text-center">
<p className="font-medium">
Welcome to our store! Free shipping on orders over $50.
</p>
</div>
</div>
);
}
export const layout = {
areaId: 'body',
sortOrder: 0
};
areaId: Where to render the component (body, content, header, etc.)sortOrder: Lower numbers render firstimport { EvershopRequest, EvershopResponse } from '@evershop/evershop';
export default (request: EvershopRequest, response: EvershopResponse) => {
response.json({
message: 'Hello from my extension!',
timestamp: new Date().toISOString()
});
};
In development mode, EverShop loads extensions from the
src/ directory. In production, it uses the compiled dist/ directory.Next Steps
- Learn about Extension Structure for detailed folder organization
- Explore Hooks and Events to react to system events
- Check out the sample extension in your EverShop installation for more examples
Troubleshooting
Extension Not Loading
Verify that:- Extension is enabled in
config/default.json - The
resolvepath is correct - You’ve rebuilt EverShop after configuration changes
TypeScript Errors
Ensure:- Dependencies are installed:
npm install - TypeScript is installed:
npm install -D typescript - Your
tsconfig.jsonis properly configured
Component Not Appearing
Check that:- The
layoutexport is present and correct - The
areaIdexists on the target page - The component file is in the correct directory
- The extension is rebuilt and EverShop is restarted