| web | ||
| .dockerignore | ||
| .gitignore | ||
| .npmrc | ||
| .prettierrc.json | ||
| Dockerfile | ||
| eslint.config.mjs | ||
| jsconfig.json | ||
| LICENSE.md | ||
| package.json | ||
| README.md | ||
| SECURITY.md | ||
Shopify App Template Using Vue v3 🟢
A template for building Shopify apps using Vue.js as the frontend. It is based on the Shopify App Node template.
Table of Contents
- Getting Started
- What is Included?
- Internationalization
- New Features in v.2.0
- FAQ
- Screenshots
- App Submission
- License
Getting Started
- Clone this repository or
git clone https://gitea.skape.store/dchar/shopify-app-template.git - Run
npm installin the root directory - Run
npm run dev:resetto configure your app (Initial setup only!) - Run
npm run devto start the app (Subsequent runs) - See
package.jsonfor other scripts
What is Included?
Vue Starter 💚
- Vue.js 3.5
- Vue Router 4 for single-page app routing
- Vue i18n for app localization
- Pinia for state management
Internationalization 🌍
Adding a New Translation
- Use
Vue i18nfor app localization. To add a new language, create a new JSON file in theLocales Folderand add the translations. See i18n.js for setup. - All translation files are lazily loaded, meaning only the translations for the current language are loaded.
- The default language is what Shopify returns via the
localequery parameter. If not set, it falls back toen. - Vue Router embeds the language in the URL, e.g.,
localhost:3000/enorlocalhost:3000/zh/about. - The template has been localized. See the
Locales Folderfolder. Translations may not be 100% accurate, so pull requests are welcome.
New Features in v.2.0
Folder Structure
Updated Structure:
root/
├── client/ # Frontend Vue app, See client README.md
├── server/ # Backend Node.js app
│ ├── database/ # DB configuration (default: SQLite)
│ ├── middleware/ # Middleware for user capture
│ ├── models/ # Models for User and Webhook
│ ├── routes/ # Default product routes
│ ├── services/ # Shopify product creator
│ ├── utils/ # Utilities (locale, webhook processing)
│ ├── webhook/ # Webhook handlers (GDPR compliance included)
│ ├── index.js # Entry point
│ └── shopify.js # Shopify configuration
- Prettier and ESLint configurations are now project-wide.
- ESLint updated to use the new flat config.
Shortcut Commands
| Command | Description |
|---|---|
npm run shopify |
Run Shopify CLI commands |
npm run build |
Build the project (frontend and backend) |
npm run dev |
Start the development server |
npm run dev:reset |
Reset Shopify configuration |
npm run dev:webhook |
Trigger a webhook. Use <domain>/api/webhooks when asked for a domain |
npm run info |
Display info about the Shopify app |
npm run generate |
Generate a theme extension |
npm run deploy |
Deploy the app |
npm run show:env |
Show environment variables for production deployment |
npm run lint |
Run ESLint on the entire project |
npm run lint:server |
Run ESLint on the server only |
npm run lint:client |
Run ESLint on the client only |
npm run format:server |
Run Prettier formatting on the server |
npm run format:client |
Run Prettier formatting on the client |
npm run client:install |
Install client dependencies |
npm run client:uninstall |
Uninstall client dependencies |
npm run server:install |
Install server dependencies |
npm run server:uninstall |
Uninstall server dependencies |
Backend Updates
- GraphQL: Removed REST resources in favor of GraphQL, as REST will soon be deprecated.
- New Models:
- User Model: Created when a user installs the app.
- Webhook Model: Tracks fired webhooks to prevent duplication.
- Webhook Processing:
- Verification and processing utilities added (new in v.2).
- Bug Fix: Fixed an issue with the product creator service.
Frontend Updates
- Renamed
helpersfolder toservices. - Updated
useAuthenticatedFetch:- Now accepts custom headers in a config object.
- Includes
enableI18nInHeadersto pass the user's locale (true by default). - Locale can be read using the
getLocalePreferencesFromRequestfunction inutils.js(server).
Deployment Enhancements
- Updated Dockerfile for simpler deployment.
- Tested on Render.com.
- Added example
shopify.app.example.tomlconfiguration file.- Allows multiple configurations (e.g.,
shopify.app.staging.toml). - Production configurations should not be committed to avoid exposing sensitive information.
- Allows multiple configurations (e.g.,
FAQ
How do I deploy this app?
Using My Own Server (Linux VPS/Render.com/Heroku)
- Set up your domain, e.g.,
https://shopify-vue.minisylar.com. - Run
npm run show:envto retrieve environment variables:
SHOPIFY_API_KEY=<YOUR_KEY>
SHOPIFY_API_SECRET=<YOUR_SECRET>
SCOPES="write_products,read_products"
HOST=https://shopify-vue.minisylar.com
Using Dockerfile
- Add the variables in the environment section of your hosting service (e.g., Render).
- Build and deploy the Dockerfile.
- For manual deployment:
docker build --build-arg SHOPIFY_API_KEY=<your_api_key> --build-arg SHOPIFY_API_SECRET=<your_api_secret> \
--build-arg SCOPES=<your_scopes> --build-arg HOST=<your_host> -t <image_name>:<tag> .
Note: Omit
<and>when providing values. Store secrets securely if using CI/CD pipelines.
How do I use MySQL or PostgreSQL for production?
MySQL Example
- import { SQLiteSessionStorage } from "@shopify/shopify-app-session-storage-sqlite";
+ import { MySQLSessionStorage } from "@shopify/shopify-app-session-storage-mysql";
sessionStorage:
process.env.NODE_ENV === "production"
? MySQLSessionStorage.withCredentials(
process.env.DATABASE_HOST,
process.env.DATABASE_SESSION,
process.env.DATABASE_USER,
process.env.DATABASE_PASSWORD,
{ connectionPoolLimit: 100 }
)
: new SQLiteSessionStorage(DB_PATH),
PostgreSQL Example
+ import { PostgreSQLSessionStorage } from "@shopify/shopify-app-session-storage-postgresql";
sessionStorage: PostgreSQLSessionStorage.withCredentials(
process.env.DATABASE_HOST,
process.env.DATABASE_SESSION,
process.env.DATABASE_USER,
process.env.DATABASE_PASSWORD
);
How to call external APIs?
Always call APIs from the server and forward responses to the frontend:
app.get("/api/external-api", async (_req, res) => {
try {
const response = await fetch("https://dummyjson.com/products", { method: "GET" });
if (response.ok) {
res.status(200).send(await response.json());
} else {
res.status(500).send({ error: "Failed to fetch data" });
}
} catch (error) {
res.status(500).send({ error: error.message });
}
});
How to resolve CORS errors?
- Verify configuration in
shopify.<your_app>.toml. - Ensure the dev domain matches the preview URL.
- Run
npm run dev:resetto reset the config, thennpm run deployto push changes.
How to update my scopes?
- Update the
scopesin your.tomlfile. See Shopify Access Scopes. - Run
npm run deploy. - Uninstall and reinstall the app in the Shopify admin dashboard.
Screenshots
App Submission
Built an app using this template? Submit it here: App submission form.