Skip to content

Commit cc3dd1a

Browse files
Merge branch 'master' into dependabot/bun/edge-apps/asset-metadata/bun-2f8a279dda
2 parents d505397 + 01158f0 commit cc3dd1a

File tree

17 files changed

+508
-32
lines changed

17 files changed

+508
-32
lines changed

.claude/skills/create-an-edge-app/SKILL.md

Lines changed: 15 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,56 +7,40 @@ description: The recommended way to create an Edge App
77

88
## When Creating an Edge App
99

10-
- Create a new directory for a new Edge App inside the `edge-apps/` directory.
11-
- The directory name should follow the `kebab-case` naming convention.
10+
- Scaffold the new Edge App using the `bun create` template from inside the `edge-apps/` directory:
11+
```bash
12+
bun create edge-app-template --no-git <app-name>
13+
```
14+
- The app name should follow the `kebab-case` naming convention.
15+
- After scaffolding, add an `id` field to `screenly.yml` and `screenly_qc.yml` before running `bun run dev`.
1216
- **Consult Figma designs** before starting implementation.
1317
- Ensure the [Figma MCP server](https://mcp.figma.com/mcp) is set up in Claude Code.
1418
- Use the Figma MCP server to access design specifications, mockups, and UI requirements.
1519
- Extract design tokens such as colors, spacing, typography, and component specifications from Figma.
1620
- Ensure the implementation matches the approved designs in Figma before proceeding with development.
1721

18-
## Directory Structure
22+
## Reference Apps
1923

20-
The new Edge App directory structure should closely resemble that of the following Edge Apps:
24+
For reference on more complex implementations, consult:
2125

22-
- QR Code (`edge-apps/qr-code/`)
23-
- Menu Board (`edge-apps/menu-board/`)
24-
- Grafana (`edge-apps/grafana/`)
25-
- CAP Alerting (`edge-apps/cap-alerting/`)
26+
- QR Code (`edge-apps/qr-code/`) — simple, low-footprint example
27+
- Menu Board (`edge-apps/menu-board/`) — more complex layout
28+
- CAP Alerting (`edge-apps/cap-alerting/`) — advanced settings and data fetching
2629

27-
These Edge Apps heavily rely on the Edge Apps library, which lives inside the `edge-apps/edge-apps-library/` directory.
28-
29-
- Most of the scripts inside the `package.json` of each of these apps execute the `edge-apps-scripts` command.
30-
- All of these apps depend on the `@screenly/edge-apps` library, which maps to `workspace:../edge-apps-library`.
31-
- `edge-apps/[new-edge-app]/src/main.ts` is a required file.
32-
- Running `bun run build` inside `edge-apps/[new-edge-app]` will run `edge-apps-scripts build`, which is very opinionated.
33-
34-
Refer to `edge-apps/qr-code/` as a complete working template to understand the full directory structure and configuration.
35-
36-
- While it still uses the `@screenly/edge-apps` library, it features a simpler implementation with a lower code footprint compared to the other aforementioned Edge Apps, making it an excellent starting point for new projects.
37-
- The library abstracts much of the complexity, allowing developers to focus on core functionality with minimal boilerplate.
30+
All apps depend on the `@screenly/edge-apps` library (`workspace:../edge-apps-library`) and use `edge-apps-scripts` for tooling.
3831

3932
### About the Manifest Files
4033

41-
The new app should have the following manifest files:
42-
43-
- `screenly.yml`
44-
- `screenly_qc.yml`
45-
46-
See `edge-apps/qr-code/screenly.yml` for a working example. More information about the manifest files can be found in the [Edge Apps documentation in the `Screenly/cli` repository](https://raw.githubusercontent.com/Screenly/cli/refs/heads/master/docs/EdgeApps.md).
47-
48-
When creating the manifest files, ensure to:
49-
50-
- Omit the `id` field, as it will be added later when the new app gets deployed.
34+
- Add any app-specific settings under the `settings` key, sorted alphabetically.
35+
- More information about manifest files can be found in the [Edge Apps documentation in the `Screenly/cli` repository](https://raw.githubusercontent.com/Screenly/cli/refs/heads/master/docs/EdgeApps.md).
5136

5237
### About `index.html`
5338

54-
The `index.html` file should follow these best practices:
5539
- Organize HTML code into templates and Web Components as the app grows in complexity.
5640
- Use HTML content templates first for simpler structures.
5741
- Consider using Web Components for more complex UI components that require encapsulation and reusability.
5842

5943
### About `README.md`
6044

6145
- Include instructions on how to create, build, test, format, lint, and deploy the app.
62-
- Do not add details like the directory structure, as the code frequently changes.
46+
- Do not add details like the directory structure, as the code frequently changes.

.prettierignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
**/*.min.js
2+
edge-apps/.bun-create/
23
edge-apps/cap-alerting/
34
edge-apps/clock/
45
edge-apps/edge-apps-library/

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,16 @@ If you are not familiar with Edge Apps, we suggest you review our [developer doc
3535
- [Weather App](https://github.com/Screenly/Playground/tree/master/edge-apps/weather) - A simple weather app.
3636
- [Welcome App](https://github.com/Screenly/Playground/tree/master/edge-apps/welcome-app) - A customizable welcome screen app.
3737

38+
### Creating a New Edge App
39+
40+
To scaffold a new Edge App, run the following from the `edge-apps/` directory:
41+
42+
```bash
43+
bun create edge-app-template --no-git <your-app-name>
44+
```
45+
46+
This generates a new app with TypeScript, the Screenly design system, manifest files, and all standard scripts pre-configured. See [`edge-apps/README.md`](/edge-apps/README.md) for full details.
47+
3848
### TypeScript Library (New)
3949

4050
The Playground also offers an Edge Apps library that contains utilities for building Edge Apps including helper functions.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
node_modules/
2+
dist/
3+
*.log
4+
.DS_Store
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules/
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# {{APP_TITLE}}
2+
3+
## Getting Started
4+
5+
```bash
6+
bun install
7+
```
8+
9+
## Deployment
10+
11+
Create and deploy the Edge App:
12+
13+
```bash
14+
screenly edge-app create --name {{APP_NAME}} --in-place
15+
bun run deploy
16+
screenly edge-app instance create
17+
```
18+
19+
## Configuration
20+
21+
The app accepts the following settings via `screenly.yml`:
22+
23+
| Setting | Description | Type | Default |
24+
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | --------------- |
25+
| `display_errors` | Display errors on screen for debugging purposes | optional | `false` |
26+
| `message` | The message to display on screen | required | `Hello, World!` |
27+
| `override_locale` | Override the default locale with a supported language code | optional | `en` |
28+
| `override_timezone` | Override the default timezone with a supported timezone identifier (e.g., `Europe/London`, `America/New_York`). Defaults to the system timezone if left blank | optional | - |
29+
30+
## Development
31+
32+
```bash
33+
bun install # Install dependencies
34+
bun run dev # Start development server
35+
```
36+
37+
## Testing
38+
39+
```bash
40+
bun test
41+
```
42+
43+
## Screenshots
44+
45+
Generate screenshots at all supported resolutions:
46+
47+
```bash
48+
bun run screenshots
49+
```
50+
51+
Screenshots are saved to the `screenshots/` directory.
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { test } from '@playwright/test'
2+
import {
3+
createMockScreenlyForScreenshots,
4+
getScreenshotsDir,
5+
RESOLUTIONS,
6+
setupScreenlyJsMock,
7+
} from '@screenly/edge-apps/test/screenshots'
8+
import path from 'path'
9+
10+
const { screenlyJsContent } = createMockScreenlyForScreenshots(
11+
{ coordinates: [40.7128, -74.006], location: 'New York, NY' },
12+
{
13+
display_errors: 'false',
14+
message: 'Hello, World!',
15+
override_locale: 'en',
16+
override_timezone: 'America/New_York',
17+
},
18+
)
19+
20+
for (const { width, height } of RESOLUTIONS) {
21+
test(`screenshot ${width}x${height}`, async ({ browser }) => {
22+
const screenshotsDir = getScreenshotsDir()
23+
24+
const context = await browser.newContext({ viewport: { width, height } })
25+
const page = await context.newPage()
26+
27+
await setupScreenlyJsMock(page, screenlyJsContent)
28+
29+
await page.goto('/')
30+
await page.waitForLoadState('networkidle')
31+
32+
await page.screenshot({
33+
path: path.join(screenshotsDir, `${width}x${height}.png`),
34+
fullPage: false,
35+
})
36+
37+
await context.close()
38+
})
39+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>{{APP_TITLE}}</title>
7+
<script src="screenly.js?version=1"></script>
8+
</head>
9+
<body>
10+
<auto-scaler
11+
reference-width="1920"
12+
reference-height="1080"
13+
orientation="auto"
14+
>
15+
<div id="app">
16+
<app-header class="header" show-date></app-header>
17+
<main class="content">
18+
<p id="message"></p>
19+
</main>
20+
</div>
21+
</auto-scaler>
22+
<script type="module" src="/src/main.ts"></script>
23+
</body>
24+
</html>
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"name": "edge-app-template",
3+
"version": "1.0.0",
4+
"type": "module",
5+
"scripts": {
6+
"prebuild": "bun run type-check",
7+
"generate-mock-data": "screenly edge-app run --generate-mock-data",
8+
"predev": "bun run generate-mock-data",
9+
"dev": "edge-apps-scripts dev",
10+
"build": "edge-apps-scripts build",
11+
"build:dev": "edge-apps-scripts build:dev",
12+
"build:prod": "edge-apps-scripts build",
13+
"test": "bun test --pass-with-no-tests src/",
14+
"test:unit": "bun test --pass-with-no-tests src/",
15+
"lint": "edge-apps-scripts lint --fix",
16+
"format": "prettier --write src/ README.md index.html",
17+
"format:check": "prettier --check src/ README.md index.html",
18+
"deploy": "bun run build && screenly edge-app deploy --path=dist/",
19+
"type-check": "edge-apps-scripts type-check",
20+
"screenshots": "edge-apps-scripts screenshots",
21+
"prepare": "cd ../edge-apps-library && bun install && bun run build"
22+
},
23+
"prettier": "../edge-apps-library/.prettierrc.json",
24+
"devDependencies": {
25+
"@playwright/test": "^1.58.0",
26+
"@screenly/edge-apps": "workspace:../edge-apps-library",
27+
"@types/bun": "^1.3.9",
28+
"@types/jsdom": "^27.0.0",
29+
"bun-types": "^1.3.9",
30+
"jsdom": "^28.1.0",
31+
"npm-run-all2": "^8.0.4",
32+
"prettier": "^3.8.1",
33+
"typescript": "^5.9.3"
34+
},
35+
"bun-create": {
36+
"postinstall": "edge-apps-scripts create"
37+
}
38+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
---
2+
syntax: manifest_v1
3+
description: {{APP_DESCRIPTION}}
4+
icon: https://playground.srly.io/edge-apps/{{APP_NAME}}/static/img/icon.svg
5+
author: Screenly, Inc.
6+
ready_signal: true
7+
settings:
8+
display_errors:
9+
type: string
10+
default_value: 'false'
11+
title: Display Errors
12+
optional: true
13+
help_text:
14+
properties:
15+
advanced: true
16+
help_text: For debugging purposes to display errors on the screen.
17+
type: boolean
18+
schema_version: 1
19+
message:
20+
type: string
21+
default_value: Hello, World!
22+
title: Message
23+
optional: false
24+
help_text: |
25+
The message to display on screen.
26+
override_locale:
27+
type: string
28+
default_value: en
29+
title: Override Locale
30+
optional: true
31+
help_text: |
32+
Override the default locale with a supported language code (e.g., en, fr, de). Defaults to English if not specified.
33+
override_timezone:
34+
type: string
35+
default_value: ''
36+
title: Override Timezone
37+
optional: true
38+
help_text: |
39+
Override the default timezone with a supported timezone identifier (e.g., Europe/London, America/New_York). Defaults to the system timezone if left blank.

0 commit comments

Comments
 (0)