Frontend
This guide details the frontend structure and functionality of the Shopify Vue App template.
Directory Structure
client/
├── src/
│ ├── assets/ # Static assets and styles
│ │ ├── base.css # Base styles and resets
│ │ ├── main.css # Main application styles
│ │ └── images/ # Image assets
│ ├── components/ # Reusable Vue components
│ │ ├── About/ # About page components
│ │ ├── Home/ # Home page components
│ │ └── NavBar/ # Navigation components
│ ├── locales/ # i18n translation files
│ │ ├── en.json # English translations
│ │ └── zh.json # Chinese translations
│ ├── plugins/ # Vue plugins and integrations
│ │ └── appBridge.js # Shopify App Bridge setup
│ ├── router/ # Vue Router configuration
│ │ └── index.js # Route definitions
│ ├── stores/ # Pinia state management
│ │ └── products.js # Product state store
│ ├── views/ # Page components
│ ├── App.vue # Root component
│ ├── i18n.js # i18n configuration
│ └── main.js # Application entry point
└── vite.config.js # Vite bundler configuration
Core Components
1. Application Entry
The main entry point (src/main.js
) initializes all core functionalities:
js
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import { i18n } from './i18n'
import App from './App.vue'
import router from './router'
const app = createApp(App)
app.use(i18n) // Enable internationalization
app.use(createPinia()) // Initialize state management
app.use(router) // Set up routing
app.mount('#app')
2. Views and Components
Page Components (/views
)
HomeView.vue
: Landing/dashboard pageAboutView.vue
: About/info pageNotFoundView.vue
: 404 error page
Navigation (/components/NavBar
)
vue
// NavBar/WelcomeNavBar.vue
<template>
<nav>
<RouterLink :to="{ name: 'home' }">
{{ $t('NavBar.home') }}
</RouterLink>
<LanguageSwitcher />
</nav>
</template>
3. State Management
The app uses Pinia for state management with modular stores:
js
// stores/products.js
export const useProductStore = defineStore('products', {
state: () => ({
products: [],
isLoading: false
}),
actions: {
async fetchProducts() {
this.isLoading = true
try {
const response = await fetch('/api/products')
this.products = await response.json()
} catch (error) {
console.error('Failed to fetch products:', error)
} finally {
this.isLoading = false
}
}
}
})
4. Routing System
Vue Router configuration with authentication and locale support:
js
// router/index.js
const router = createRouter({
history: createWebHistory(),
routes: [
{
path: '/:locale?',
children: [
{
path: '',
name: 'home',
component: HomeView
}
]
}
]
})
// i18n navigation guard
router.beforeEach(async (to, from, next) => {
// Handle locale routing
const locale = to.params.locale || i18n.global.locale
await loadLocaleMessages(i18n, locale)
next()
})
5. Internationalization (i18n)
Multi-language support configuration:
js
// i18n.js
import { createI18n } from 'vue-i18n'
export const SUPPORT_LOCALES = ['en', 'zh']
export const i18n = createI18n({
locale: localStorage.getItem('app_locale') || 'en',
fallbackLocale: 'en',
messages: {}
})
// Usage in components
const { t } = useI18n()
<h1>{{ t('HomePage.title') }}</h1>
Translation structure:
json
// locales/en.json
{
"NavBar": {
"home": "Home",
"about": "About"
},
"HomePage": {
"title": "Welcome",
"description": "Start building your Shopify app"
}
}
6. Shopify Integration
App Bridge Setup
js
// plugins/appBridge.js
import { shopify } from '@shopify/app-bridge'
const config = {
apiKey: process.env.SHOPIFY_API_KEY,
host: new URLSearchParams(location.search).get('host'),
forceRedirect: true
}
export const appBridge = shopify.createApp(config)
App Bridge Usage
js
// Toast notifications
appBridge.toast.show('Operation successful!')
// Navigation
appBridge.navigate.toCard('settings')
// Modal dialogs
appBridge.modal.open({
title: 'Confirmation',
message: 'Are you sure?'
})
7. API Communication
Authenticated API requests using App Bridge:
js
// Example API call
async function fetchProducts() {
try {
const response = await fetch('/api/products/count')
if (!response.ok) throw new Error('API Error')
return await response.json()
} catch (error) {
appBridge.toast.show(error.message, { isError: true })
}
}
Development Tools
1. Vite Configuration
js
// vite.config.js
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': '/src'
}
},
server: {
hmr: hmrConfig,
proxy: {
'^/api': {
target: process.env.BACKEND_URL,
changeOrigin: true
}
}
}
})
2. TypeScript Support
json
// tsconfig.json
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"strict": true,
"jsx": "preserve",
"types": ["@shopify/app-bridge-types"]
}
}
Security Best Practices
- XSS Prevention
- Use Vue's template syntax
- Sanitize user input
- Enable CSP headers
- Authentication
- Secure session handling
- Token management
- HTTPS enforcement
- Data Protection
- Client-side validation
- Secure storage practices
- Error handling
Error Handling
- API Errors
js
try {
const response = await fetch('/api/products')
if (!response.ok) throw new Error('API Error')
} catch (error) {
appBridge.toast.show(error.message, { isError: true })
}
- Component Error Boundaries
vue
<ErrorBoundary @error="handleError">
<SuspenseComponent />
</ErrorBoundary>
Performance Optimization
- Code Splitting
- Route-based code splitting
- Async components
- Dynamic imports
- Asset Optimization
- Image optimization
- CSS minification
- Tree shaking
Best Practices
- Component Organization
- Single responsibility
- Proper naming
- Clear props/emits
- TypeScript types
- State Management
- Clear store modules
- Computed properties
- Action composition
- Type safety
- Code Style
- ESLint configuration
- Prettier formatting
- Component conventions
- Documentation
Environment Configuration
Configure environment variables in .env
:
VITE_SHOPIFY_API_KEY= # Your Shopify API key
VITE_HOST= # App host URL
VITE_BACKEND_URL= # Backend API URL
Debugging
- Vue DevTools
- Component inspection
- State management
- Timeline events
- Router debugging
- Console Logging
- Development-only logging
- Error tracking
- Performance monitoring
Deployment
- Build Process
bash
# Production build
npm run build
# Preview build
npm run preview
- Build Output
- Optimized assets
- Source maps
- Static files