nuxt-telegram-mini-app 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +2 -0
- package/.vscode/settings.json +55 -0
- package/.vscode/tailwind.json +55 -0
- package/CONTRIBUTING.md +406 -0
- package/LICENSE +21 -0
- package/README.md +640 -0
- package/app/app.vue +87 -0
- package/app/assets/css/main.css +53 -0
- package/app/assets/css/tailwind.css +3 -0
- package/app/components/ErrorBoundary.vue +81 -0
- package/app/components/Hero.vue +61 -0
- package/app/components/tg/Button.vue +128 -0
- package/app/components/tg/Cell.vue +91 -0
- package/app/components/tg/Content.vue +42 -0
- package/app/components/tg/Nav.vue +107 -0
- package/app/components/tg/Section.vue +50 -0
- package/app/composables/telegram.ts +342 -0
- package/app/error.vue +161 -0
- package/app/pages/components.vue +279 -0
- package/app/pages/functions.vue +107 -0
- package/app/pages/index.vue +211 -0
- package/app/pages/utilities.vue +402 -0
- package/app/types/telegram-webapp.ts +160 -0
- package/app/utils/color.ts +37 -0
- package/eslint.config.mjs +6 -0
- package/nuxt.config.ts +55 -0
- package/package.json +46 -0
- package/public/_redirects +2 -0
- package/public/favicon.ico +0 -0
- package/public/img/hero-user.svg +8 -0
- package/public/img/nuxt-logo.svg +11 -0
- package/public/robots.txt +2 -0
- package/server/api/verify-telegram-data.post.ts +150 -0
- package/tailwind.config.ts +39 -0
- package/tests/components.spec.ts +311 -0
- package/tests/pages.spec.ts +426 -0
- package/tests/telegram.spec.ts +105 -0
- package/tests/utils.spec.ts +47 -0
- package/tsconfig.json +18 -0
- package/vitest.config.ts +24 -0
package/README.md
ADDED
|
@@ -0,0 +1,640 @@
|
|
|
1
|
+
# ๐ Nuxt Telegram Mini App Template
|
|
2
|
+
|
|
3
|
+
A comprehensive template for building Telegram Mini Apps using Nuxt 4, Vue 3, TypeScript, and Tailwind CSS, ready for deployment on Netlify.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+

|
|
7
|
+

|
|
8
|
+

|
|
9
|
+

|
|
10
|
+
|
|
11
|
+
## โจ Features
|
|
12
|
+
|
|
13
|
+
### ๐ฏ Core Features
|
|
14
|
+
- **๐ง Complete Nuxt 4 Setup** - Latest Nuxt with TypeScript support
|
|
15
|
+
- **๐ฑ Telegram WebApp SDK** - Full integration with Telegram Mini App APIs
|
|
16
|
+
- **๐จ Tailwind CSS** - Utility-first CSS framework with Telegram theme integration
|
|
17
|
+
- **โก SPA Mode** - Optimized for Telegram Mini App deployment
|
|
18
|
+
- **๐ Netlify Ready** - Pre-configured for seamless deployment
|
|
19
|
+
|
|
20
|
+
### ๐งฉ Components Library
|
|
21
|
+
- **TgButton** - Telegram-styled buttons with haptic feedback
|
|
22
|
+
- **TgCell** - List cells with navigation and interaction support
|
|
23
|
+
- **TgContent** - Main content wrapper with proper spacing
|
|
24
|
+
- **TgNav** - Bottom navigation bar with up to 4 menu options and icons
|
|
25
|
+
- **TgSection** - Content sections with proper styling
|
|
26
|
+
- **Hero** - Header component for pages
|
|
27
|
+
|
|
28
|
+
### ๐ก Telegram SDK Integration
|
|
29
|
+
- **๐ฎ Haptic Feedback** - Impact, notification, and selection feedback
|
|
30
|
+
- **๐ Main Button** - Configurable main action button
|
|
31
|
+
- **โฌ
๏ธ Back Button** - Navigation back button control
|
|
32
|
+
- **๐ค User Data** - Access to Telegram user information
|
|
33
|
+
- **๐จ Theme Integration** - Automatic Telegram theme colors
|
|
34
|
+
- **๐ Viewport Control** - Responsive viewport management
|
|
35
|
+
- **๐ Deep Linking** - External and Telegram link handling
|
|
36
|
+
- **๐ค Sharing** - Built-in sharing functionality
|
|
37
|
+
|
|
38
|
+
### ๐งช Testing & Quality
|
|
39
|
+
- **โก Vitest** - Fast unit testing framework
|
|
40
|
+
- **๐งช Component Tests** - Comprehensive test coverage
|
|
41
|
+
- **๐ TypeScript** - Full type safety
|
|
42
|
+
- **๐ Type Definitions** - Complete Telegram WebApp types
|
|
43
|
+
|
|
44
|
+
## ๐ Quick Start
|
|
45
|
+
|
|
46
|
+
### Prerequisites
|
|
47
|
+
- Node.js 18+
|
|
48
|
+
- npm or yarn or pnpm
|
|
49
|
+
|
|
50
|
+
### 1. Use This Template
|
|
51
|
+
Click the "Use this template" button on GitHub or clone the repository:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
git clone https://github.com/patricktobias86/nuxt-telegram-mini-app.git my-telegram-app
|
|
55
|
+
cd my-telegram-app
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### 2. Install Dependencies
|
|
59
|
+
```bash
|
|
60
|
+
npm install
|
|
61
|
+
# or
|
|
62
|
+
yarn install
|
|
63
|
+
# or
|
|
64
|
+
pnpm install
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### 3. Development
|
|
68
|
+
```bash
|
|
69
|
+
npm run dev
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Open [http://localhost:3000](http://localhost:3000) in your browser to see the demo.
|
|
73
|
+
|
|
74
|
+
### 4. Build for Production
|
|
75
|
+
```bash
|
|
76
|
+
npm run generate
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## ๐ Project Structure
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
โโโ app/ # Nuxt app directory
|
|
84
|
+
โ โโโ assets/ # CSS and static assets
|
|
85
|
+
โ โ โโโ css/
|
|
86
|
+
โ โ โโโ main.css # Global styles
|
|
87
|
+
โ โ โโโ tailwind.css # Tailwind imports
|
|
88
|
+
โ โโโ components/ # Vue components
|
|
89
|
+
โ โ โโโ Hero.vue # Hero component
|
|
90
|
+
โ โ โโโ ErrorBoundary.vue
|
|
91
|
+
โ โ โโโ tg/ # Telegram components
|
|
92
|
+
โ โ โโโ Button.vue # Telegram button
|
|
93
|
+
โ โ โโโ Cell.vue # List cell
|
|
94
|
+
โ โ โโโ Content.vue # Content wrapper
|
|
95
|
+
โ โ โโโ Nav.vue # Bottom navigation
|
|
96
|
+
โ โ โโโ Section.vue # Content section
|
|
97
|
+
โ โโโ composables/ # Vue composables
|
|
98
|
+
โ โ โโโ telegram.ts # Telegram SDK integration
|
|
99
|
+
โ โโโ pages/ # App pages
|
|
100
|
+
โ โ โโโ index.vue # Home page with SDK demo
|
|
101
|
+
โ โ โโโ components.vue # Components showcase
|
|
102
|
+
โ โ โโโ utilities.vue # Utilities demo
|
|
103
|
+
โ โ โโโ functions.vue # Functions page
|
|
104
|
+
โ โโโ types/ # TypeScript definitions
|
|
105
|
+
โ โ โโโ telegram-webapp.ts
|
|
106
|
+
โ โโโ utils/ # Utility functions
|
|
107
|
+
โ โโโ color.ts # Color conversion utilities
|
|
108
|
+
โโโ server/ # Nuxt server API
|
|
109
|
+
โ โโโ api/
|
|
110
|
+
โ โโโ verify-telegram-data.post.ts # Telegram data verification
|
|
111
|
+
โโโ public/ # Static assets
|
|
112
|
+
โโโ tests/ # Test files
|
|
113
|
+
โ โโโ telegram.spec.ts
|
|
114
|
+
โโโ nuxt.config.ts # Nuxt configuration
|
|
115
|
+
โโโ tailwind.config.ts # Tailwind configuration
|
|
116
|
+
โโโ vitest.config.ts # Test configuration
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## ๐ฏ Usage Guide
|
|
120
|
+
|
|
121
|
+
### Creating Your First Page
|
|
122
|
+
|
|
123
|
+
1. **Create a new page** in `app/pages/`:
|
|
124
|
+
```vue
|
|
125
|
+
<!-- app/pages/my-page.vue -->
|
|
126
|
+
<template>
|
|
127
|
+
<TgContent>
|
|
128
|
+
<Hero
|
|
129
|
+
title="My Page"
|
|
130
|
+
subtitle="Description of my page"
|
|
131
|
+
image-src="/img/hero-user.svg"
|
|
132
|
+
/>
|
|
133
|
+
|
|
134
|
+
<TgSection title="My Section" inset>
|
|
135
|
+
<TgCell
|
|
136
|
+
title="My Cell"
|
|
137
|
+
subtitle="Cell description"
|
|
138
|
+
icon="i-heroicons-star-20-solid"
|
|
139
|
+
/>
|
|
140
|
+
</TgSection>
|
|
141
|
+
</TgContent>
|
|
142
|
+
</template>
|
|
143
|
+
|
|
144
|
+
<script setup lang="ts">
|
|
145
|
+
import { ref } from 'vue'
|
|
146
|
+
import { useRouter } from 'vue-router'
|
|
147
|
+
|
|
148
|
+
const router = useRouter()
|
|
149
|
+
const goHome = () => router.push('/')
|
|
150
|
+
</script>
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Using Telegram SDK Features
|
|
154
|
+
|
|
155
|
+
```vue
|
|
156
|
+
<script setup lang="ts">
|
|
157
|
+
import {
|
|
158
|
+
useMainButton,
|
|
159
|
+
useBackButton,
|
|
160
|
+
useHapticFeedback,
|
|
161
|
+
useInitData,
|
|
162
|
+
useThemeParams
|
|
163
|
+
} from '~/composables/telegram'
|
|
164
|
+
|
|
165
|
+
const main = useMainButton()
|
|
166
|
+
const back = useBackButton()
|
|
167
|
+
const haptic = useHapticFeedback()
|
|
168
|
+
const init = useInitData()
|
|
169
|
+
const theme = useThemeParams()
|
|
170
|
+
|
|
171
|
+
// Configure main button
|
|
172
|
+
onMounted(() => {
|
|
173
|
+
main.mount()
|
|
174
|
+
main.setParams({
|
|
175
|
+
is_visible: true,
|
|
176
|
+
is_active: true,
|
|
177
|
+
text: 'My Action'
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
const off = main.onClick(() => {
|
|
181
|
+
haptic.impactOccurred('medium')
|
|
182
|
+
// Your action here
|
|
183
|
+
})
|
|
184
|
+
|
|
185
|
+
onBeforeUnmounted(() => off?.())
|
|
186
|
+
})
|
|
187
|
+
|
|
188
|
+
// Access user data
|
|
189
|
+
const userName = computed(() => init.user.value?.first_name || 'Guest')
|
|
190
|
+
|
|
191
|
+
// Use theme colors
|
|
192
|
+
const bgColor = computed(() => theme.backgroundColor.value)
|
|
193
|
+
</script>
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Custom Components
|
|
197
|
+
|
|
198
|
+
The template includes pre-built Telegram-styled components:
|
|
199
|
+
|
|
200
|
+
```vue
|
|
201
|
+
<!-- Buttons -->
|
|
202
|
+
<TgButton title="Primary" status="primary" haptic @click="handleClick" />
|
|
203
|
+
<TgButton title="Secondary" status="secondary" haptic="impact-light" />
|
|
204
|
+
<TgButton title="Outline" status="outline" />
|
|
205
|
+
<TgButton title="Destructive" status="destructive" />
|
|
206
|
+
|
|
207
|
+
<!-- Cells -->
|
|
208
|
+
<TgCell title="Basic Cell" subtitle="With subtitle" />
|
|
209
|
+
<TgCell title="With Icon" icon="i-heroicons-star-20-solid" />
|
|
210
|
+
<TgCell title="Navigable" to="/target-page" />
|
|
211
|
+
<TgCell title="Interactive" @click="handleCellClick" />
|
|
212
|
+
|
|
213
|
+
<!-- Sections -->
|
|
214
|
+
<TgSection title="My Section" inset>
|
|
215
|
+
<!-- Section content -->
|
|
216
|
+
</TgSection>
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## ๐งฉ Using as a Nuxt Layer
|
|
220
|
+
|
|
221
|
+
This template is compatible with Nuxt Layers, allowing you to use it as a reusable layer in other Nuxt projects or extend it with additional layers.
|
|
222
|
+
|
|
223
|
+
### What are Nuxt Layers?
|
|
224
|
+
|
|
225
|
+
Nuxt Layers provide a way to extend and customize Nuxt applications by sharing configurations, components, pages, composables, and more across multiple projects. Layers can be local directories or published npm packages.
|
|
226
|
+
|
|
227
|
+
### Using This Template as a Layer
|
|
228
|
+
|
|
229
|
+
To use this Telegram Mini App template as a layer in another Nuxt project:
|
|
230
|
+
|
|
231
|
+
1. **Clone or reference the layer**:
|
|
232
|
+
```bash
|
|
233
|
+
# Option 1: Clone as a subdirectory
|
|
234
|
+
git clone https://github.com/patricktobias86/nuxt-telegram-mini-app.git layers/telegram-app
|
|
235
|
+
|
|
236
|
+
# Option 2: Add as git dependency (recommended for teams)
|
|
237
|
+
# In your project's package.json:
|
|
238
|
+
# "dependencies": {
|
|
239
|
+
# "nuxt-telegram-mini-app": "github:patricktobias86/nuxt-telegram-mini-app"
|
|
240
|
+
# }
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
2. **Configure your Nuxt project** to extend this layer:
|
|
244
|
+
```ts
|
|
245
|
+
// nuxt.config.ts
|
|
246
|
+
export default defineNuxtConfig({
|
|
247
|
+
extends: [
|
|
248
|
+
// Local path
|
|
249
|
+
'./layers/telegram-app',
|
|
250
|
+
// Or npm package
|
|
251
|
+
// 'nuxt-telegram-mini-app'
|
|
252
|
+
],
|
|
253
|
+
// Your custom config here
|
|
254
|
+
})
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
3. **Access layer features** in your project:
|
|
258
|
+
- **Components**: Use `<TgButton>`, `<TgCell>`, etc. in your pages
|
|
259
|
+
- **Composables**: Import `useMainButton`, `useHapticFeedback`, etc.
|
|
260
|
+
- **Pages**: Extend or override existing pages
|
|
261
|
+
- **Styles**: Inherit Tailwind and Telegram theme integration
|
|
262
|
+
|
|
263
|
+
### Extending This Layer
|
|
264
|
+
|
|
265
|
+
This template includes an `extends: []` configuration, allowing you to further extend it with additional layers:
|
|
266
|
+
|
|
267
|
+
```ts
|
|
268
|
+
// nuxt.config.ts in this template
|
|
269
|
+
export default defineNuxtConfig({
|
|
270
|
+
extends: [
|
|
271
|
+
// Add your custom layers here
|
|
272
|
+
// './layers/my-custom-layer',
|
|
273
|
+
// 'my-published-layer'
|
|
274
|
+
],
|
|
275
|
+
// ... rest of config
|
|
276
|
+
})
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Layer Structure
|
|
280
|
+
|
|
281
|
+
The template follows Nuxt's layer conventions:
|
|
282
|
+
- `app/` directory contains all extendable content
|
|
283
|
+
- `nuxt.config.ts` at root level defines layer configuration
|
|
284
|
+
- Components, pages, and composables are automatically merged
|
|
285
|
+
|
|
286
|
+
### Best Practices
|
|
287
|
+
|
|
288
|
+
- **Override selectively**: Only override what you need to customize
|
|
289
|
+
- **Maintain compatibility**: Keep Telegram SDK integration intact
|
|
290
|
+
- **Test thoroughly**: Ensure Telegram features work in your extended app
|
|
291
|
+
- **Version control**: Pin layer versions for stability
|
|
292
|
+
|
|
293
|
+
## ๐ Deployment
|
|
294
|
+
|
|
295
|
+
### Manual Deployment
|
|
296
|
+
|
|
297
|
+
1. **Build the project**:
|
|
298
|
+
```bash
|
|
299
|
+
npm run generate
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
2. **Deploy the `dist` folder** to your hosting provider
|
|
303
|
+
|
|
304
|
+
### Netlify (SPA routing)
|
|
305
|
+
|
|
306
|
+
- This project uses Vue Router history mode to preserve Telegram's `#tgWebAppData` hash.
|
|
307
|
+
- Netlify requires a SPA redirect so deep links resolve to `index.html`.
|
|
308
|
+
- Included file: `public/_redirects` with `/* /index.html 200`.
|
|
309
|
+
- If you deploy elsewhere, add an equivalent history fallback rule.
|
|
310
|
+
|
|
311
|
+
### Environment Variables
|
|
312
|
+
|
|
313
|
+
Set these in your deployment platform:
|
|
314
|
+
|
|
315
|
+
```env
|
|
316
|
+
ENV=production
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
## ๐งช Testing
|
|
320
|
+
|
|
321
|
+
Run tests with:
|
|
322
|
+
|
|
323
|
+
```bash
|
|
324
|
+
# Run tests once
|
|
325
|
+
npm run test
|
|
326
|
+
|
|
327
|
+
# Run tests in watch mode
|
|
328
|
+
npm run test:watch
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
The project includes:
|
|
332
|
+
- **Unit tests** for Telegram composables
|
|
333
|
+
- **Component tests** for UI components
|
|
334
|
+
- **Integration tests** for user flows
|
|
335
|
+
|
|
336
|
+
## ๐จ Customization
|
|
337
|
+
|
|
338
|
+
### Theme Customization
|
|
339
|
+
|
|
340
|
+
The template automatically inherits Telegram's theme colors. Customize in `app/assets/css/main.css`:
|
|
341
|
+
|
|
342
|
+
```css
|
|
343
|
+
:root {
|
|
344
|
+
/* Telegram theme variables are automatically set */
|
|
345
|
+
--custom-color: #your-color;
|
|
346
|
+
}
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
### Tailwind Configuration
|
|
350
|
+
|
|
351
|
+
Extend Tailwind in `tailwind.config.ts`:
|
|
352
|
+
|
|
353
|
+
```ts
|
|
354
|
+
export default {
|
|
355
|
+
theme: {
|
|
356
|
+
extend: {
|
|
357
|
+
colors: {
|
|
358
|
+
'custom': '#your-color',
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### Adding New Components
|
|
366
|
+
|
|
367
|
+
1. Create component in `app/components/`
|
|
368
|
+
2. Follow the existing patterns for styling and props
|
|
369
|
+
3. Add TypeScript interfaces for props
|
|
370
|
+
4. Include tests in `tests/`
|
|
371
|
+
|
|
372
|
+
## ๐ API Reference
|
|
373
|
+
|
|
374
|
+
### Composables
|
|
375
|
+
|
|
376
|
+
#### `useTelegramWebApp()`
|
|
377
|
+
- `webApp` - WebApp instance
|
|
378
|
+
- `isReady` - Ready state
|
|
379
|
+
- `isAvailable` - Availability check
|
|
380
|
+
|
|
381
|
+
#### `useMainButton()`
|
|
382
|
+
- `setParams(params)` - Configure button
|
|
383
|
+
- `onClick(callback)` - Handle clicks
|
|
384
|
+
- `visible` - Visibility state
|
|
385
|
+
|
|
386
|
+
#### `useBackButton()`
|
|
387
|
+
- `show()` / `hide()` - Control visibility
|
|
388
|
+
- `onClick(callback)` - Handle clicks
|
|
389
|
+
|
|
390
|
+
#### `useHapticFeedback()`
|
|
391
|
+
- `impactOccurred(style)` - Trigger impact
|
|
392
|
+
- `notificationOccurred(type)` - Trigger notification
|
|
393
|
+
- `selectionChanged()` - Trigger selection
|
|
394
|
+
|
|
395
|
+
#### `useInitData()`
|
|
396
|
+
- `user` - User information
|
|
397
|
+
- `queryId` - Query ID
|
|
398
|
+
- `startParam` - Start parameter
|
|
399
|
+
|
|
400
|
+
#### `useThemeParams()`
|
|
401
|
+
- `backgroundColor` - Theme background
|
|
402
|
+
- `textColor` - Theme text color
|
|
403
|
+
- `buttonColor` - Theme button color
|
|
404
|
+
- And more theme colors...
|
|
405
|
+
|
|
406
|
+
### Components
|
|
407
|
+
|
|
408
|
+
#### `<TgButton>`
|
|
409
|
+
Props-driven styling so you donโt need extra Tailwind classes.
|
|
410
|
+
|
|
411
|
+
```vue
|
|
412
|
+
<TgButton
|
|
413
|
+
title="Label"
|
|
414
|
+
status="primary|secondary|outline|danger|destructive"
|
|
415
|
+
size="sm|md|lg"
|
|
416
|
+
:block="true"
|
|
417
|
+
:loading="false"
|
|
418
|
+
:disabled="false"
|
|
419
|
+
icon="i-heroicons-star-20-solid"
|
|
420
|
+
icon-position="left|right"
|
|
421
|
+
elevated
|
|
422
|
+
uppercase
|
|
423
|
+
haptic="selection|impact-light|impact-medium|impact-heavy|notification-success|notification-warning|notification-error"
|
|
424
|
+
@click="handleClick"
|
|
425
|
+
/>
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
TgButton props
|
|
429
|
+
|
|
430
|
+
| Prop | Required | Default | Description |
|
|
431
|
+
| --- | --- | --- | --- |
|
|
432
|
+
| `title` | yes | โ | Button label text |
|
|
433
|
+
| `status` | no | `primary` | Visual style variant |
|
|
434
|
+
| `size` | no | `md` | Size of the button |
|
|
435
|
+
| `block` | no | `true` | Full width when true |
|
|
436
|
+
| `loading` | no | `false` | Shows spinner and disables |
|
|
437
|
+
| `disabled` | no | `false` | Disables interaction |
|
|
438
|
+
| `icon` | no | โ | Icon name for `@nuxt/icon` |
|
|
439
|
+
| `icon-position` | no | `left` | Icon placement relative to text |
|
|
440
|
+
| `elevated` | no | `false` | Adds a subtle shadow |
|
|
441
|
+
| `uppercase` | no | `false` | Uppercase label |
|
|
442
|
+
| `to` | no | โ | Internal route, uses `NuxtLink` |
|
|
443
|
+
| `href` | no | โ | External link, uses `<a>` |
|
|
444
|
+
| `share-url` | no | โ | Triggers Telegram share on click |
|
|
445
|
+
| `haptic` | no | `false` | Haptic feedback type or boolean |
|
|
446
|
+
|
|
447
|
+
Notes:
|
|
448
|
+
- Prefer `to` (router) for internal navigation to avoid conflicts with bottom Nav.
|
|
449
|
+
- `small` is still supported but `size` is preferred.
|
|
450
|
+
|
|
451
|
+
#### `<TgCell>`
|
|
452
|
+
```vue
|
|
453
|
+
<TgCell
|
|
454
|
+
title="Cell Title"
|
|
455
|
+
subtitle="Cell Subtitle"
|
|
456
|
+
:description="dynamicDescription"
|
|
457
|
+
icon="i-heroicons-star-20-solid"
|
|
458
|
+
color="var(--tg-theme-link-color)"
|
|
459
|
+
icon-color="#888"
|
|
460
|
+
tone="default|secondary"
|
|
461
|
+
:border="true"
|
|
462
|
+
:clickable="false"
|
|
463
|
+
:chevron="undefined|true|false"
|
|
464
|
+
to="/navigation-target"
|
|
465
|
+
href="https://example.com"
|
|
466
|
+
@click="handleClick"
|
|
467
|
+
/>
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
TgCell props
|
|
471
|
+
|
|
472
|
+
| Prop | Required | Default | Description |
|
|
473
|
+
| --- | --- | --- | --- |
|
|
474
|
+
| `title` | no | `''` | Title text |
|
|
475
|
+
| `subtitle` | no | โ | Subtitle text |
|
|
476
|
+
| `description` | no | โ | Description text |
|
|
477
|
+
| `icon` | no | โ | Icon name for `@nuxt/icon` |
|
|
478
|
+
| `color` | no | โ | Title color override |
|
|
479
|
+
| `icon-color` | no | โ | Icon color override |
|
|
480
|
+
| `line-clamp` | no | `0` | Clamp lines for text (0 = none) |
|
|
481
|
+
| `border` | no | `true` | Bottom divider line |
|
|
482
|
+
| `tone` | no | `default` | Background tone |
|
|
483
|
+
| `clickable` | no | `false` | Hover style even without link |
|
|
484
|
+
| `chevron` | no | `auto` | Force chevron visibility |
|
|
485
|
+
| `to` | no | โ | Internal route, uses `NuxtLink` |
|
|
486
|
+
| `href` | no | โ | External link, uses `<a>` |
|
|
487
|
+
|
|
488
|
+
#### `<TgContent>`
|
|
489
|
+
```vue
|
|
490
|
+
<TgContent as="main|section|div" />
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
Behavior
|
|
494
|
+
|
|
495
|
+
- Automatically adds bottom safe-area padding when a `<TgNav>` exists on the page.
|
|
496
|
+
- Default container styles: `max-w-2xl`, `p-4`, and `space-y-6`.
|
|
497
|
+
|
|
498
|
+
TgContent props
|
|
499
|
+
|
|
500
|
+
| Prop | Required | Default | Description |
|
|
501
|
+
| --- | --- | --- | --- |
|
|
502
|
+
| `as` | no | `main` | Render element |
|
|
503
|
+
| `max-width-class` | no | โ | Optional override for container max width |
|
|
504
|
+
| `class` | no | `''` | Extra classes to merge |
|
|
505
|
+
|
|
506
|
+
#### `<TgSection>`
|
|
507
|
+
```vue
|
|
508
|
+
<TgSection title="Section" inset tone="default|secondary" :append-border="true" />
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
Behavior
|
|
512
|
+
|
|
513
|
+
- Rounded corners by default; larger rounding when `inset`.
|
|
514
|
+
- No outer border around the body.
|
|
515
|
+
|
|
516
|
+
TgSection props
|
|
517
|
+
|
|
518
|
+
| Prop | Required | Default | Description |
|
|
519
|
+
| --- | --- | --- | --- |
|
|
520
|
+
| `title` | no | โ | Optional section header |
|
|
521
|
+
| `inset` | no | `false` | Indented, iOS-like style |
|
|
522
|
+
| `tone` | no | `default` | Background tone for body |
|
|
523
|
+
| `append-border` | no | `true` | Thin border above append slot |
|
|
524
|
+
| `class` | no | `''` | Extra classes on wrapper |
|
|
525
|
+
|
|
526
|
+
#### `<TgNav>`
|
|
527
|
+
```vue
|
|
528
|
+
<TgNav
|
|
529
|
+
:items="navItems"
|
|
530
|
+
:model-value="activeKey"
|
|
531
|
+
tone="default|secondary"
|
|
532
|
+
:border="true"
|
|
533
|
+
height="12|14"
|
|
534
|
+
:safe-area="true"
|
|
535
|
+
root-class="custom-nav-class"
|
|
536
|
+
@select="handleSelect"
|
|
537
|
+
@update:model-value="handleActiveChange"
|
|
538
|
+
/>
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
TgNav props
|
|
542
|
+
|
|
543
|
+
| Prop | Required | Default | Description |
|
|
544
|
+
| --- | --- | --- | --- |
|
|
545
|
+
| `items` | yes | โ | List of items `{ key, label, icon?, to? }` |
|
|
546
|
+
| `model-value` | no | โ | Controlled active key |
|
|
547
|
+
| `tone` | no | `default` | Background tone |
|
|
548
|
+
| `border` | no | `true` | Top border visibility |
|
|
549
|
+
| `height` | no | `14` | Item height (Tailwind number) |
|
|
550
|
+
| `safe-area` | no | `true` | Adds bottom safe area spacer |
|
|
551
|
+
| `root-class` | no | `''` | Extra classes on root nav |
|
|
552
|
+
|
|
553
|
+
Navigation items structure:
|
|
554
|
+
```ts
|
|
555
|
+
interface TgNavItem {
|
|
556
|
+
key: string // Unique identifier
|
|
557
|
+
label: string // Display text
|
|
558
|
+
icon?: string // Icon name (optional)
|
|
559
|
+
to?: string // Route path (optional)
|
|
560
|
+
}
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
Routing guidance
|
|
564
|
+
|
|
565
|
+
- Use `to` (router) for internal navigation to avoid conflicts with the fixed `<TgNav>`.
|
|
566
|
+
- Reserve `href` for external links.
|
|
567
|
+
|
|
568
|
+
## ๐ง Configuration
|
|
569
|
+
|
|
570
|
+
### Nuxt Configuration
|
|
571
|
+
|
|
572
|
+
Key settings in `nuxt.config.ts`:
|
|
573
|
+
|
|
574
|
+
```ts
|
|
575
|
+
export default defineNuxtConfig({
|
|
576
|
+
ssr: false, // SPA mode for Telegram
|
|
577
|
+
srcDir: 'app', // App source directory
|
|
578
|
+
router: {
|
|
579
|
+
options: {
|
|
580
|
+
// Use history mode so Telegram's #tgWebAppData is not rewritten to a route
|
|
581
|
+
hashMode: false
|
|
582
|
+
}
|
|
583
|
+
},
|
|
584
|
+
modules: [
|
|
585
|
+
'@nuxt/icon', // Icon support
|
|
586
|
+
'@nuxtjs/tailwindcss', // Tailwind CSS
|
|
587
|
+
],
|
|
588
|
+
app: {
|
|
589
|
+
head: {
|
|
590
|
+
script: [{
|
|
591
|
+
src: 'https://telegram.org/js/telegram-web-app.js?58',
|
|
592
|
+
defer: true
|
|
593
|
+
}]
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
})
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
### Telegram WebApp Script
|
|
600
|
+
|
|
601
|
+
The template automatically includes the Telegram WebApp script. The version can be updated in the Nuxt config.
|
|
602
|
+
|
|
603
|
+
## ๐ค Contributing
|
|
604
|
+
|
|
605
|
+
1. **Fork** the repository
|
|
606
|
+
2. **Create** a feature branch
|
|
607
|
+
3. **Make** your changes
|
|
608
|
+
4. **Add** tests for new features
|
|
609
|
+
5. **Submit** a pull request
|
|
610
|
+
|
|
611
|
+
## ๐ License
|
|
612
|
+
|
|
613
|
+
MIT License - see [LICENSE](LICENSE) file for details.
|
|
614
|
+
|
|
615
|
+
## ๐ Support
|
|
616
|
+
|
|
617
|
+
- **๐ Documentation**: Check this README and inline code comments
|
|
618
|
+
- **๐ Issues**: Report bugs via GitHub Issues
|
|
619
|
+
- **๐ก Discussions**: Use GitHub Discussions for questions
|
|
620
|
+
- **๐ Telegram Docs**: [Telegram Mini Apps Documentation](https://core.telegram.org/bots/webapps)
|
|
621
|
+
|
|
622
|
+
## ๐๏ธ Built With
|
|
623
|
+
|
|
624
|
+
- [Nuxt 4](https://nuxt.com/) - The Vue.js Framework
|
|
625
|
+
- [Vue 3](https://vuejs.org/) - The Progressive JavaScript Framework
|
|
626
|
+
- [TypeScript](https://www.typescriptlang.org/) - JavaScript with syntax for types
|
|
627
|
+
- [Tailwind CSS](https://tailwindcss.com/) - A utility-first CSS framework
|
|
628
|
+
- [Vitest](https://vitest.dev/) - A blazing fast unit testing framework
|
|
629
|
+
- [Telegram WebApp API](https://core.telegram.org/bots/webapps) - Telegram Mini Apps Platform
|
|
630
|
+
|
|
631
|
+
## ๐ Links
|
|
632
|
+
|
|
633
|
+
- [Demo](https://your-demo-url.netlify.app) - Live demo
|
|
634
|
+
- [Telegram Mini Apps Guide](https://core.telegram.org/bots/webapps)
|
|
635
|
+
- [Nuxt 4 Documentation](https://nuxt.com/docs)
|
|
636
|
+
- [Vue 3 Documentation](https://vuejs.org/guide/)
|
|
637
|
+
|
|
638
|
+
---
|
|
639
|
+
|
|
640
|
+
**Made with โค๏ธ using Nuxt 4**
|