├── .dockerignore ├── .eslintrc.cjs ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── build.md │ ├── chore.md │ ├── ci.md │ ├── config.yml │ ├── documentation.md │ ├── feature_request.md │ ├── performance.md │ ├── refactor.md │ ├── revert.md │ ├── style.md │ └── test.md ├── PULL_REQUEST_TEMPLATE.md ├── dependabot.yml └── workflows │ └── main.yaml ├── .gitignore ├── .prettierignore ├── .prettierrc ├── .vscode └── settings.json ├── Dockerfile ├── LICENSE ├── README.md ├── astro.config.mjs ├── components.json ├── cspell.config.yaml ├── docker-compose.yaml ├── package-lock.json ├── package.json ├── public ├── .well-known │ └── microsoft-identity-association ├── CNAME ├── apple-touch-icon.png ├── blog │ └── open-graph.png ├── favicon.svg ├── fonts │ └── GeneralSans │ │ ├── GeneralSans-Bold.otf │ │ ├── GeneralSans-BoldItalic.otf │ │ ├── GeneralSans-Extralight.otf │ │ ├── GeneralSans-ExtralightItalic.otf │ │ ├── GeneralSans-Italic.otf │ │ ├── GeneralSans-Light.otf │ │ ├── GeneralSans-LightItalic.otf │ │ ├── GeneralSans-Medium.otf │ │ ├── GeneralSans-MediumItalic.otf │ │ ├── GeneralSans-Regular.otf │ │ ├── GeneralSans-Semibold.otf │ │ └── GeneralSans-SemiboldItalic.otf ├── legal │ └── Shorebird DPA online template EU, UK and Swiss 2024-09-07.docx.pdf ├── open-graph.png └── success-stories │ └── open-graph.png ├── src ├── assets │ ├── blog │ │ ├── brand-refresh │ │ │ ├── color-palette.png │ │ │ ├── new-site-design.png │ │ │ └── refreshed-logo.png │ │ ├── covers │ │ │ ├── 1.0-cover.png │ │ │ ├── brand-refresh-cover.png │ │ │ ├── buy-dont-build-cover.png │ │ │ ├── code-push-v2-cover.png │ │ │ ├── codemagic-cover.png │ │ │ ├── custom-tracks-cover.png │ │ │ ├── dart-3.5-cover.png │ │ │ ├── dart-macros-cover.png │ │ │ ├── development-workflow-cover.png │ │ │ ├── flutter-3.32-cover.png │ │ │ ├── flutter-jobs-cover.png │ │ │ ├── flutterconusa-2025-cover.png │ │ │ ├── how-we-built-code-push-cover.png │ │ │ ├── improved-cloud-infra-cover.png │ │ │ ├── improved-patch-delivery-cover.png │ │ │ ├── ios-beta-cover.png │ │ │ ├── macos-beta-cover.png │ │ │ ├── organizations-cover.png │ │ │ ├── patch-rollback-cover.png │ │ │ ├── patch-signing-cover.png │ │ │ ├── simplified-pricing-cover.png │ │ │ ├── stable-desktop-cover.png │ │ │ ├── tom-joins-shorebird-cover.png │ │ │ ├── tracks-cover.png │ │ │ ├── viewing-logs-cover.png │ │ │ ├── windows-beta-cover.png │ │ │ ├── workshops-cover.png │ │ │ └── yearly-plans-cover.png │ │ ├── flutter-3.32-release │ │ │ └── apple-squircle.jpg │ │ ├── flutterconusa-2025-sponsor │ │ │ └── register-now-banner.jpg │ │ ├── headshots │ │ │ ├── bryan-headshot.png │ │ │ ├── eric-headshot.jpeg │ │ │ ├── felix-headshot.jpeg │ │ │ ├── shorebird-headshot.png │ │ │ └── tom-headshot.jpg │ │ ├── improved-cloud-infra │ │ │ ├── customer-facing-service-load.png │ │ │ ├── insights-page-loads.png │ │ │ ├── insights-tab.png │ │ │ ├── patch-check-latency-improvements.png │ │ │ ├── patch-installs-30d.png │ │ │ └── traffic-comparison.png │ │ ├── improved-patch-delivery │ │ │ └── china-availability.png │ │ ├── release-logs │ │ │ ├── ConsolePatchCheckResponse.png │ │ │ ├── ConsoleShowProcessMenu.png │ │ │ ├── EmptyConsoleStartButtonArrow.png │ │ │ └── TerminalLogcat.png │ │ ├── simplified-pricing │ │ │ ├── ProPlan.png │ │ │ └── UsageLimit.png │ │ └── windows-desktop │ │ │ └── screenshot.png │ ├── brands │ │ ├── apna-klub.png │ │ ├── chai.png │ │ ├── flash-co.png │ │ ├── invoice-home.png │ │ ├── junglee.png │ │ ├── kalshi.png │ │ ├── kijiji.png │ │ ├── pushpress.png │ │ ├── solides.png │ │ ├── tracker.png │ │ └── tradeling.png │ ├── features │ │ ├── all-platforms.png │ │ ├── any-code.png │ │ ├── compliance.png │ │ ├── quick-fix.png │ │ ├── releases.png │ │ ├── rollback.png │ │ └── social-proof.png │ ├── resources │ │ ├── discord.png │ │ └── shorebird.png │ ├── success-stories │ │ └── covers │ │ │ ├── easyspend-cover.png │ │ │ ├── junglee-games-cover.png │ │ │ ├── kijiji-cover.png │ │ │ ├── pushpress-cover.png │ │ │ ├── solides-cover.png │ │ │ └── visible-cover.png │ ├── team │ │ ├── bryan-headshot.png │ │ ├── eric-headshot.jpeg │ │ ├── felix-headshot.jpeg │ │ └── tom-headshot.jpg │ └── testimonials │ │ ├── david-paul.jpg │ │ ├── esra-kadah.png │ │ ├── jason-rai.png │ │ ├── renan-araujo.png │ │ ├── scott-macdougall.jpeg │ │ └── taha-tesser.png ├── components │ ├── blog │ │ ├── blog-callout.tsx │ │ └── formatted-date.astro │ ├── ellipse.tsx │ ├── home │ │ ├── blog-overview.astro │ │ ├── brands.astro │ │ ├── callout.astro │ │ ├── faq-overview.tsx │ │ ├── faq.astro │ │ ├── features.astro │ │ ├── for-developers.astro │ │ ├── for-teams.astro │ │ ├── hero-motion.tsx │ │ ├── hero.astro │ │ ├── pricing-overview.astro │ │ ├── problem.astro │ │ ├── resources.astro │ │ ├── solution.astro │ │ ├── success-stories-overview.astro │ │ └── testimonials.astro │ ├── logos │ │ ├── discord-logo.tsx │ │ ├── flutter-logo.tsx │ │ ├── github-logo.tsx │ │ ├── linkedin-logo.tsx │ │ ├── logo-full.tsx │ │ └── twitter-logo.tsx │ ├── newsletter │ │ └── newsletter-form.tsx │ ├── pricing │ │ ├── pricing-calculator.tsx │ │ ├── pricing-details.astro │ │ ├── pricing-faq.tsx │ │ └── pricing-plans.tsx │ ├── scroll-to-top-button.tsx │ └── ui │ │ ├── accordion.tsx │ │ ├── button.tsx │ │ ├── card.tsx │ │ ├── footer.astro │ │ ├── input.tsx │ │ ├── markdown.tsx │ │ ├── marquee.tsx │ │ ├── navbar.tsx │ │ ├── sheet.tsx │ │ ├── slider.tsx │ │ ├── spacer.tsx │ │ └── table.tsx ├── config.ts ├── content │ ├── blog │ │ ├── 1.0.md │ │ ├── brand-refresh.md │ │ ├── buy-dont-build.md │ │ ├── cloud-infra-improvements.md │ │ ├── custom-tracks.md │ │ ├── dart-3.5.0.md │ │ ├── dart-macros.md │ │ ├── desktop-in-production.md │ │ ├── development-workflow.md │ │ ├── flutter-3.32-release.md │ │ ├── flutter-jobs.md │ │ ├── flutterconusa-2025-sponsor.md │ │ ├── how-we-built-code-push.md │ │ ├── improved-patch-delivery.md │ │ ├── ios-beta.md │ │ ├── macos-beta.md │ │ ├── organizations.md │ │ ├── patch-rollback.md │ │ ├── patch-signing-beta.md │ │ ├── shorebird-code-push-v2.md │ │ ├── shorebird-codemagic.md │ │ ├── simplified-pricing.md │ │ ├── tom-joins-shorebird.md │ │ ├── tracks-percentage-rollouts-a-b-testing.md │ │ ├── viewing-logs.md │ │ ├── windows-beta.md │ │ ├── workshops.md │ │ └── yearly-plans.md │ ├── config.ts │ └── success-stories │ │ ├── easyspend.md │ │ ├── junglee-games.md │ │ ├── kijiji.md │ │ ├── push-press.md │ │ ├── solides.md │ │ └── visible.md ├── layouts │ ├── blog.astro │ ├── main.astro │ ├── markdown.astro │ └── success-story.astro ├── lib │ └── utils.ts ├── motion │ └── hero-motion.json ├── pages │ ├── about.astro │ ├── blog │ │ ├── [...slug].astro │ │ └── index.astro │ ├── contact.md │ ├── demo.html │ ├── index.astro │ ├── jobs.md │ ├── legal │ │ └── dpa.md │ ├── newsletter-signup.astro │ ├── pricing.astro │ ├── privacy │ │ ├── index.md │ │ └── raw.ts │ ├── success-stories │ │ ├── [...slug].astro │ │ └── index.astro │ └── terms │ │ ├── index.md │ │ └── raw.ts └── styles │ └── global.css ├── tailwind.config.ts └── tsconfig.json /.dockerignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | /node_modules 3 | 4 | # Production 5 | /build 6 | 7 | # Misc 8 | .DS_Store 9 | 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | -------------------------------------------------------------------------------- /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['plugin:astro/recommended'], 3 | overrides: [ 4 | { 5 | // Define the configuration for `.astro` file. 6 | files: ['*.astro'], 7 | // Allows Astro components to be parsed. 8 | parser: 'astro-eslint-parser', 9 | // Parse the script in `.ast 10 | // It's the setting you need when using TypeScript. 11 | parserOptions: { 12 | parser: '@typescript-eslint/parser', 13 | extraFileExtensions: ['.astro'], 14 | }, 15 | }, 16 | ], 17 | }; 18 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug Report 3 | about: Create a report to help us improve 4 | title: 'fix: ' 5 | labels: bug 6 | --- 7 | 8 | **Description** 9 | 10 | A clear and concise description of what the bug is. 11 | 12 | **Steps To Reproduce** 13 | 14 | 1. Go to '...' 15 | 2. Click on '....' 16 | 3. Scroll down to '....' 17 | 4. See error 18 | 19 | **Expected Behavior** 20 | 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | 25 | If applicable, add screenshots to help explain your problem. 26 | 27 | **Additional Context** 28 | 29 | Add any other context about the problem here. 30 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/build.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Build System 3 | about: Changes that affect the build system or external dependencies 4 | title: 'build: ' 5 | labels: build 6 | --- 7 | 8 | **Description** 9 | 10 | Describe what changes need to be done to the build system and why. 11 | 12 | **Requirements** 13 | 14 | - [ ] The build system is passing 15 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/chore.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Chore 3 | about: Other changes that don't modify src or test files 4 | title: 'chore: ' 5 | labels: chore 6 | --- 7 | 8 | **Description** 9 | 10 | Clearly describe what change is needed and why. If this changes code then please 11 | use another issue type. 12 | 13 | **Requirements** 14 | 15 | - [ ] No functional changes to the code 16 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/ci.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Continuous Integration 3 | about: Changes to the CI configuration files and scripts 4 | title: 'ci: ' 5 | labels: ci 6 | --- 7 | 8 | **Description** 9 | 10 | Describe what changes need to be done to the ci/cd system and why. 11 | 12 | **Requirements** 13 | 14 | - [ ] The ci system is passing 15 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/documentation.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Documentation 3 | about: 4 | Improve the documentation so all collaborators have a common understanding 5 | title: 'docs: ' 6 | labels: documentation 7 | --- 8 | 9 | **Description** 10 | 11 | Clearly describe what documentation you are looking to add or improve. 12 | 13 | **Requirements** 14 | 15 | - [ ] Requirements go here 16 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature Request 3 | about: A new feature to be added to the project 4 | title: 'feat: ' 5 | labels: feature 6 | --- 7 | 8 | **Description** 9 | 10 | Clearly describe what you are looking to add. The more context the better. 11 | 12 | **Requirements** 13 | 14 | - [ ] Checklist of requirements to be fulfilled 15 | 16 | **Additional Context** 17 | 18 | Add any other context or screenshots about the feature request go here. 19 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/performance.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Performance Update 3 | about: A code change that improves performance 4 | title: 'perf: ' 5 | labels: performance 6 | --- 7 | 8 | **Description** 9 | 10 | Clearly describe what code needs to be changed and what the performance impact 11 | is going to be. Bonus point's if you can tie this directly to user experience. 12 | 13 | **Requirements** 14 | 15 | - [ ] There is no drop in test coverage. 16 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/refactor.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Refactor 3 | about: A code change that neither fixes a bug nor adds a feature 4 | title: 'refactor: ' 5 | labels: refactor 6 | --- 7 | 8 | **Description** 9 | 10 | Clearly describe what needs to be refactored and why. Please provide links to 11 | related issues (bugs or upcoming features) in order to help prioritize. 12 | 13 | **Requirements** 14 | 15 | - [ ] There is no drop in test coverage. 16 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/revert.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Revert Commit 3 | about: Reverts a previous commit 4 | title: 'revert: ' 5 | labels: revert 6 | --- 7 | 8 | **Description** 9 | 10 | Provide a link to a PR/Commit that you are looking to revert and why. 11 | 12 | **Requirements** 13 | 14 | - [ ] Change has been reverted 15 | - [ ] No change in test coverage has happened 16 | - [ ] A new ticket is created for any follow on work that needs to happen 17 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/style.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Style Changes 3 | about: 4 | Changes that do not affect the meaning of the code (white-space, formatting, 5 | missing semi-colons, etc) 6 | title: 'style: ' 7 | labels: style 8 | --- 9 | 10 | **Description** 11 | 12 | Clearly describe what you are looking to change and why. 13 | 14 | **Requirements** 15 | 16 | - [ ] There is no drop in test coverage. 17 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/test.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Test 3 | about: Adding missing tests or correcting existing tests 4 | title: 'test: ' 5 | labels: test 6 | --- 7 | 8 | **Description** 9 | 10 | List out the tests that need to be added or changed. Please also include any 11 | information as to why this was not covered in the past. 12 | 13 | **Requirements** 14 | 15 | - [ ] There is no drop in test coverage. 16 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | ## Status 8 | 9 | **READY/IN DEVELOPMENT/HOLD** 10 | 11 | ## Description 12 | 13 | 14 | 15 | ## Type of Change 16 | 17 | 18 | 19 | - [ ] ✨ New feature (non-breaking change which adds functionality) 20 | - [ ] 🛠️ Bug fix (non-breaking change which fixes an issue) 21 | - [ ] ❌ Breaking change (fix or feature that would cause existing functionality 22 | to change) 23 | - [ ] 🧹 Code refactor 24 | - [ ] ✅ Build configuration change 25 | - [ ] 📝 Documentation 26 | - [ ] 🗑️ Chore 27 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: 'github-actions' 9 | directory: '/' 10 | schedule: 11 | interval: 'weekly' 12 | groups: 13 | gha-deps: 14 | patterns: 15 | - '*' 16 | - package-ecosystem: 'npm' 17 | directory: '/' 18 | schedule: 19 | interval: 'weekly' 20 | groups: 21 | npm-deps: 22 | patterns: 23 | - '*' 24 | -------------------------------------------------------------------------------- /.github/workflows/main.yaml: -------------------------------------------------------------------------------- 1 | name: ci 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: 7 | - main 8 | 9 | jobs: 10 | build: 11 | runs-on: macos-latest 12 | 13 | steps: 14 | - name: 📚 Git Checkout 15 | uses: actions/checkout@v4 16 | 17 | - name: ⚙️ Setup Node 18 | uses: actions/setup-node@v4 19 | with: 20 | node-version: 22.12.x 21 | cache: npm 22 | cache-dependency-path: package-lock.json 23 | 24 | - name: 📦 Install Dependencies 25 | run: npm ci 26 | 27 | - name: ✨ Check Format 28 | run: npm run format:check 29 | 30 | - name: 🧹 Lint 31 | run: npm run lint 32 | 33 | - name: 🔤 Check Spelling 34 | run: npm run cspell "**" 35 | 36 | - name: 👷 Build website 37 | run: npm run build 38 | 39 | deploy: 40 | needs: build 41 | 42 | runs-on: macos-latest 43 | 44 | if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} 45 | 46 | steps: 47 | - name: 📚 Git Checkout 48 | uses: actions/checkout@v4 49 | 50 | - name: ⚙️ Setup Node 51 | uses: actions/setup-node@v4 52 | with: 53 | node-version: 22.12.x 54 | cache: npm 55 | cache-dependency-path: package-lock.json 56 | 57 | - name: 📦 Install Dependencies 58 | run: npm ci 59 | 60 | - name: ✨ Check Format 61 | run: npm run format:check 62 | 63 | - name: 🧹 Lint 64 | run: npm run lint 65 | 66 | - name: 🔤 Check Spelling 67 | run: npm run cspell 68 | 69 | - name: 👷 Build website 70 | run: npm run build 71 | 72 | - name: ☁️ Deploy to GitHub Pages 73 | uses: peaceiris/actions-gh-pages@v4 74 | with: 75 | github_token: ${{ secrets.GITHUB_TOKEN }} 76 | publish_dir: ./dist 77 | user_name: github-actions[bot] 78 | user_email: 41898282+github-actions[bot]@users.noreply.github.com 79 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # build output 2 | dist/ 3 | .output/ 4 | 5 | # generated types 6 | .astro/ 7 | 8 | # dependencies 9 | node_modules/ 10 | 11 | # logs 12 | npm-debug.log* 13 | yarn-debug.log* 14 | yarn-error.log* 15 | pnpm-debug.log* 16 | 17 | # environment variables 18 | .env 19 | .env.production 20 | 21 | # macOS-specific files 22 | .DS_Store 23 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | src/motion/* 2 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["prettier-plugin-tailwindcss"], 3 | "singleQuote": true, 4 | "printWidth": 80, 5 | "proseWrap": "always" 6 | } 7 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "node_modules/typescript/lib" 3 | } 4 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:lts as base 2 | 3 | WORKDIR /app 4 | 5 | COPY ./package.json ./ 6 | COPY ./package-lock.json ./ 7 | 8 | RUN npm ci 9 | 10 | COPY . . 11 | 12 | EXPOSE 3000 35729 13 | 14 | ENTRYPOINT npm start -- --host 0.0.0.0 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Shorebird Site 🐦 2 | 3 | Home of the [shorebird.dev](https://shorebird.dev) site. 4 | 5 | ## Running with Docker 🐳 6 | 7 | ``` 8 | docker compose up --build 9 | ``` 10 | -------------------------------------------------------------------------------- /astro.config.mjs: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | import { defineConfig } from 'astro/config'; 3 | import tailwindcss from '@tailwindcss/vite'; 4 | import react from '@astrojs/react'; 5 | import sitemap from '@astrojs/sitemap'; 6 | import config from './src/config'; 7 | 8 | // https://astro.build/config 9 | export default defineConfig({ 10 | site: 'https://shorebird.dev', 11 | vite: { 12 | plugins: [tailwindcss()], 13 | }, 14 | integrations: [react(), sitemap()], 15 | redirects: { 16 | '/faq': 'https://docs.shorebird.dev/faq', 17 | '/privacy.html': '/privacy', 18 | '/security': 'https://handbook.shorebird.dev/security', 19 | // Initially tweeted the wrong link: 20 | '/success-stories/pushpress/': '/success-stories/push-press', 21 | '/talk-to-sales': config.contactSales, 22 | '/terms.html': '/terms', 23 | '/workshops': 'https://calendly.com/felix-shorebird/shorebird-workshop', 24 | }, 25 | }); 26 | -------------------------------------------------------------------------------- /components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "new-york", 4 | "rsc": false, 5 | "tsx": true, 6 | "tailwind": { 7 | "config": "", 8 | "css": "src/styles/global.css", 9 | "baseColor": "neutral", 10 | "cssVariables": true, 11 | "prefix": "" 12 | }, 13 | "aliases": { 14 | "components": "@/components", 15 | "utils": "@/lib/utils", 16 | "ui": "@/components/ui", 17 | "lib": "@/lib", 18 | "hooks": "@/hooks" 19 | }, 20 | "iconLibrary": "lucide" 21 | } 22 | -------------------------------------------------------------------------------- /cspell.config.yaml: -------------------------------------------------------------------------------- 1 | $schema: https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json 2 | version: '0.2' 3 | ignorePaths: ['dist', 'node_modules'] 4 | words: 5 | - afonso 6 | - angelov 7 | - apna 8 | - araujo 9 | - arra 10 | - astro 11 | - astrojs 12 | - autoplay 13 | - bhavesh 14 | - BIGL 15 | - bryanoltman 16 | - cancelbots 17 | - codemagic 18 | - cupertino 19 | - devnomic 20 | - dougall 21 | - dominik 22 | - droidcon 23 | - eseidel 24 | - esra 25 | - evenodd 26 | - felangel 27 | - felangelov 28 | - findstr 29 | - fintech 30 | - fluttercon 31 | - flutterconusa 32 | - fontsource 33 | - FOUC 34 | - frontmatter 35 | - ghisi 36 | - grayscale 37 | - headshot 38 | - headshots 39 | - howzat 40 | - ITAR 41 | - jsxs 42 | - junglee 43 | - kalshi 44 | - kadah 45 | - kijiji 46 | - klub 47 | - leeming 48 | - logcat 49 | - macdougall 50 | - mailchimp 51 | - mairramer 52 | - nubank 53 | - oltman 54 | - onclick 55 | - Palo 56 | - Posthog 57 | - pubspec 58 | - pushpress 59 | - renan 60 | - rollout 61 | - rollouts 62 | - roszkowski 63 | - seidel 64 | - shorebirddev 65 | - shorebirdtech 66 | - siclen 67 | - signups 68 | - signup 69 | - solides 70 | - souza 71 | - squircle 72 | - squircles 73 | - superlist 74 | - taha 75 | - techlead 76 | - tesser 77 | - thiago 78 | - tomarra 79 | - tradeling 80 | - tsconfigs 81 | - upvoted 82 | - userbase 83 | - veloso 84 | - xlink 85 | -------------------------------------------------------------------------------- /docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | 3 | volumes: 4 | node_modules: 5 | 6 | services: 7 | shorebird-site: 8 | build: . 9 | container_name: shorebird-site 10 | stdin_open: true 11 | tty: true 12 | ports: 13 | - 4321:4321 14 | - 35729:35729 15 | volumes: 16 | - ./:/app 17 | - node_modules:/app/node_modules 18 | working_dir: /app 19 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "website", 3 | "type": "module", 4 | "version": "0.0.1", 5 | "scripts": { 6 | "dev": "astro dev", 7 | "build": "astro build", 8 | "preview": "astro preview", 9 | "astro": "astro", 10 | "format": "prettier --write .", 11 | "format:check": "prettier --check .", 12 | "lint": "", 13 | "cspell": "cspell \"**\"" 14 | }, 15 | "dependencies": { 16 | "@astrojs/mdx": "^4.3.0", 17 | "@astrojs/react": "^4.3.0", 18 | "@astrojs/sitemap": "^3.4.0", 19 | "@base-ui-components/react": "^1.0.0-beta.0", 20 | "@phosphor-icons/react": "^2.1.10", 21 | "@radix-ui/react-accordion": "^1.2.11", 22 | "@radix-ui/react-dialog": "^1.1.14", 23 | "@radix-ui/react-slot": "^1.1.2", 24 | "@tailwindcss/vite": "^4.1.8", 25 | "@types/react": "^19.1.6", 26 | "@types/react-dom": "^19.1.5", 27 | "astro": "^5.8.1", 28 | "class-variance-authority": "^0.7.1", 29 | "clsx": "^2.1.1", 30 | "lottie-react": "^2.4.1", 31 | "lucide-react": "^0.511.0", 32 | "react": "^19.1.0", 33 | "react-dom": "^19.1.0", 34 | "react-markdown": "^10.1.0", 35 | "tailwind-merge": "^3.3.0", 36 | "tailwindcss": "^4.0.3", 37 | "tailwindcss-animate": "^1.0.7" 38 | }, 39 | "devDependencies": { 40 | "@tailwindcss/typography": "^0.5.16", 41 | "cspell": "^9.0.2", 42 | "prettier": "^3.4.2", 43 | "prettier-plugin-astro": "^0.14.1", 44 | "prettier-plugin-tailwindcss": "^0.6.12" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /public/.well-known/microsoft-identity-association: -------------------------------------------------------------------------------- 1 | { 2 | "associatedApplications": [ 3 | { 4 | "applicationId": "4fc38981-4ec4-4bd9-a755-e6ad9a413054" 5 | } 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /public/CNAME: -------------------------------------------------------------------------------- 1 | shorebird.dev -------------------------------------------------------------------------------- /public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/public/apple-touch-icon.png -------------------------------------------------------------------------------- /public/blog/open-graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/public/blog/open-graph.png -------------------------------------------------------------------------------- /public/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /public/fonts/GeneralSans/GeneralSans-Bold.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/public/fonts/GeneralSans/GeneralSans-Bold.otf -------------------------------------------------------------------------------- /public/fonts/GeneralSans/GeneralSans-BoldItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/public/fonts/GeneralSans/GeneralSans-BoldItalic.otf -------------------------------------------------------------------------------- /public/fonts/GeneralSans/GeneralSans-Extralight.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/public/fonts/GeneralSans/GeneralSans-Extralight.otf -------------------------------------------------------------------------------- /public/fonts/GeneralSans/GeneralSans-ExtralightItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/public/fonts/GeneralSans/GeneralSans-ExtralightItalic.otf -------------------------------------------------------------------------------- /public/fonts/GeneralSans/GeneralSans-Italic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/public/fonts/GeneralSans/GeneralSans-Italic.otf -------------------------------------------------------------------------------- /public/fonts/GeneralSans/GeneralSans-Light.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/public/fonts/GeneralSans/GeneralSans-Light.otf -------------------------------------------------------------------------------- /public/fonts/GeneralSans/GeneralSans-LightItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/public/fonts/GeneralSans/GeneralSans-LightItalic.otf -------------------------------------------------------------------------------- /public/fonts/GeneralSans/GeneralSans-Medium.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/public/fonts/GeneralSans/GeneralSans-Medium.otf -------------------------------------------------------------------------------- /public/fonts/GeneralSans/GeneralSans-MediumItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/public/fonts/GeneralSans/GeneralSans-MediumItalic.otf -------------------------------------------------------------------------------- /public/fonts/GeneralSans/GeneralSans-Regular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/public/fonts/GeneralSans/GeneralSans-Regular.otf -------------------------------------------------------------------------------- /public/fonts/GeneralSans/GeneralSans-Semibold.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/public/fonts/GeneralSans/GeneralSans-Semibold.otf -------------------------------------------------------------------------------- /public/fonts/GeneralSans/GeneralSans-SemiboldItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/public/fonts/GeneralSans/GeneralSans-SemiboldItalic.otf -------------------------------------------------------------------------------- /public/legal/Shorebird DPA online template EU, UK and Swiss 2024-09-07.docx.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/public/legal/Shorebird DPA online template EU, UK and Swiss 2024-09-07.docx.pdf -------------------------------------------------------------------------------- /public/open-graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/public/open-graph.png -------------------------------------------------------------------------------- /public/success-stories/open-graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/public/success-stories/open-graph.png -------------------------------------------------------------------------------- /src/assets/blog/brand-refresh/color-palette.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/brand-refresh/color-palette.png -------------------------------------------------------------------------------- /src/assets/blog/brand-refresh/new-site-design.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/brand-refresh/new-site-design.png -------------------------------------------------------------------------------- /src/assets/blog/brand-refresh/refreshed-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/brand-refresh/refreshed-logo.png -------------------------------------------------------------------------------- /src/assets/blog/covers/1.0-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/covers/1.0-cover.png -------------------------------------------------------------------------------- /src/assets/blog/covers/brand-refresh-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/covers/brand-refresh-cover.png -------------------------------------------------------------------------------- /src/assets/blog/covers/buy-dont-build-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/covers/buy-dont-build-cover.png -------------------------------------------------------------------------------- /src/assets/blog/covers/code-push-v2-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/covers/code-push-v2-cover.png -------------------------------------------------------------------------------- /src/assets/blog/covers/codemagic-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/covers/codemagic-cover.png -------------------------------------------------------------------------------- /src/assets/blog/covers/custom-tracks-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/covers/custom-tracks-cover.png -------------------------------------------------------------------------------- /src/assets/blog/covers/dart-3.5-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/covers/dart-3.5-cover.png -------------------------------------------------------------------------------- /src/assets/blog/covers/dart-macros-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/covers/dart-macros-cover.png -------------------------------------------------------------------------------- /src/assets/blog/covers/development-workflow-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/covers/development-workflow-cover.png -------------------------------------------------------------------------------- /src/assets/blog/covers/flutter-3.32-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/covers/flutter-3.32-cover.png -------------------------------------------------------------------------------- /src/assets/blog/covers/flutter-jobs-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/covers/flutter-jobs-cover.png -------------------------------------------------------------------------------- /src/assets/blog/covers/flutterconusa-2025-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/covers/flutterconusa-2025-cover.png -------------------------------------------------------------------------------- /src/assets/blog/covers/how-we-built-code-push-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/covers/how-we-built-code-push-cover.png -------------------------------------------------------------------------------- /src/assets/blog/covers/improved-cloud-infra-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/covers/improved-cloud-infra-cover.png -------------------------------------------------------------------------------- /src/assets/blog/covers/improved-patch-delivery-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/covers/improved-patch-delivery-cover.png -------------------------------------------------------------------------------- /src/assets/blog/covers/ios-beta-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/covers/ios-beta-cover.png -------------------------------------------------------------------------------- /src/assets/blog/covers/macos-beta-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/covers/macos-beta-cover.png -------------------------------------------------------------------------------- /src/assets/blog/covers/organizations-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/covers/organizations-cover.png -------------------------------------------------------------------------------- /src/assets/blog/covers/patch-rollback-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/covers/patch-rollback-cover.png -------------------------------------------------------------------------------- /src/assets/blog/covers/patch-signing-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/covers/patch-signing-cover.png -------------------------------------------------------------------------------- /src/assets/blog/covers/simplified-pricing-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/covers/simplified-pricing-cover.png -------------------------------------------------------------------------------- /src/assets/blog/covers/stable-desktop-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/covers/stable-desktop-cover.png -------------------------------------------------------------------------------- /src/assets/blog/covers/tom-joins-shorebird-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/covers/tom-joins-shorebird-cover.png -------------------------------------------------------------------------------- /src/assets/blog/covers/tracks-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/covers/tracks-cover.png -------------------------------------------------------------------------------- /src/assets/blog/covers/viewing-logs-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/covers/viewing-logs-cover.png -------------------------------------------------------------------------------- /src/assets/blog/covers/windows-beta-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/covers/windows-beta-cover.png -------------------------------------------------------------------------------- /src/assets/blog/covers/workshops-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/covers/workshops-cover.png -------------------------------------------------------------------------------- /src/assets/blog/covers/yearly-plans-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/covers/yearly-plans-cover.png -------------------------------------------------------------------------------- /src/assets/blog/flutter-3.32-release/apple-squircle.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/flutter-3.32-release/apple-squircle.jpg -------------------------------------------------------------------------------- /src/assets/blog/flutterconusa-2025-sponsor/register-now-banner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/flutterconusa-2025-sponsor/register-now-banner.jpg -------------------------------------------------------------------------------- /src/assets/blog/headshots/bryan-headshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/headshots/bryan-headshot.png -------------------------------------------------------------------------------- /src/assets/blog/headshots/eric-headshot.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/headshots/eric-headshot.jpeg -------------------------------------------------------------------------------- /src/assets/blog/headshots/felix-headshot.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/headshots/felix-headshot.jpeg -------------------------------------------------------------------------------- /src/assets/blog/headshots/shorebird-headshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/headshots/shorebird-headshot.png -------------------------------------------------------------------------------- /src/assets/blog/headshots/tom-headshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/headshots/tom-headshot.jpg -------------------------------------------------------------------------------- /src/assets/blog/improved-cloud-infra/customer-facing-service-load.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/improved-cloud-infra/customer-facing-service-load.png -------------------------------------------------------------------------------- /src/assets/blog/improved-cloud-infra/insights-page-loads.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/improved-cloud-infra/insights-page-loads.png -------------------------------------------------------------------------------- /src/assets/blog/improved-cloud-infra/insights-tab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/improved-cloud-infra/insights-tab.png -------------------------------------------------------------------------------- /src/assets/blog/improved-cloud-infra/patch-check-latency-improvements.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/improved-cloud-infra/patch-check-latency-improvements.png -------------------------------------------------------------------------------- /src/assets/blog/improved-cloud-infra/patch-installs-30d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/improved-cloud-infra/patch-installs-30d.png -------------------------------------------------------------------------------- /src/assets/blog/improved-cloud-infra/traffic-comparison.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/improved-cloud-infra/traffic-comparison.png -------------------------------------------------------------------------------- /src/assets/blog/improved-patch-delivery/china-availability.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/improved-patch-delivery/china-availability.png -------------------------------------------------------------------------------- /src/assets/blog/release-logs/ConsolePatchCheckResponse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/release-logs/ConsolePatchCheckResponse.png -------------------------------------------------------------------------------- /src/assets/blog/release-logs/ConsoleShowProcessMenu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/release-logs/ConsoleShowProcessMenu.png -------------------------------------------------------------------------------- /src/assets/blog/release-logs/EmptyConsoleStartButtonArrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/release-logs/EmptyConsoleStartButtonArrow.png -------------------------------------------------------------------------------- /src/assets/blog/release-logs/TerminalLogcat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/release-logs/TerminalLogcat.png -------------------------------------------------------------------------------- /src/assets/blog/simplified-pricing/ProPlan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/simplified-pricing/ProPlan.png -------------------------------------------------------------------------------- /src/assets/blog/simplified-pricing/UsageLimit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/simplified-pricing/UsageLimit.png -------------------------------------------------------------------------------- /src/assets/blog/windows-desktop/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/blog/windows-desktop/screenshot.png -------------------------------------------------------------------------------- /src/assets/brands/apna-klub.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/brands/apna-klub.png -------------------------------------------------------------------------------- /src/assets/brands/chai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/brands/chai.png -------------------------------------------------------------------------------- /src/assets/brands/flash-co.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/brands/flash-co.png -------------------------------------------------------------------------------- /src/assets/brands/invoice-home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/brands/invoice-home.png -------------------------------------------------------------------------------- /src/assets/brands/junglee.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/brands/junglee.png -------------------------------------------------------------------------------- /src/assets/brands/kalshi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/brands/kalshi.png -------------------------------------------------------------------------------- /src/assets/brands/kijiji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/brands/kijiji.png -------------------------------------------------------------------------------- /src/assets/brands/pushpress.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/brands/pushpress.png -------------------------------------------------------------------------------- /src/assets/brands/solides.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/brands/solides.png -------------------------------------------------------------------------------- /src/assets/brands/tracker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/brands/tracker.png -------------------------------------------------------------------------------- /src/assets/brands/tradeling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/brands/tradeling.png -------------------------------------------------------------------------------- /src/assets/features/all-platforms.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/features/all-platforms.png -------------------------------------------------------------------------------- /src/assets/features/any-code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/features/any-code.png -------------------------------------------------------------------------------- /src/assets/features/compliance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/features/compliance.png -------------------------------------------------------------------------------- /src/assets/features/quick-fix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/features/quick-fix.png -------------------------------------------------------------------------------- /src/assets/features/releases.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/features/releases.png -------------------------------------------------------------------------------- /src/assets/features/rollback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/features/rollback.png -------------------------------------------------------------------------------- /src/assets/features/social-proof.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/features/social-proof.png -------------------------------------------------------------------------------- /src/assets/resources/discord.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/resources/discord.png -------------------------------------------------------------------------------- /src/assets/resources/shorebird.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/resources/shorebird.png -------------------------------------------------------------------------------- /src/assets/success-stories/covers/easyspend-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/success-stories/covers/easyspend-cover.png -------------------------------------------------------------------------------- /src/assets/success-stories/covers/junglee-games-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/success-stories/covers/junglee-games-cover.png -------------------------------------------------------------------------------- /src/assets/success-stories/covers/kijiji-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/success-stories/covers/kijiji-cover.png -------------------------------------------------------------------------------- /src/assets/success-stories/covers/pushpress-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/success-stories/covers/pushpress-cover.png -------------------------------------------------------------------------------- /src/assets/success-stories/covers/solides-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/success-stories/covers/solides-cover.png -------------------------------------------------------------------------------- /src/assets/success-stories/covers/visible-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/success-stories/covers/visible-cover.png -------------------------------------------------------------------------------- /src/assets/team/bryan-headshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/team/bryan-headshot.png -------------------------------------------------------------------------------- /src/assets/team/eric-headshot.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/team/eric-headshot.jpeg -------------------------------------------------------------------------------- /src/assets/team/felix-headshot.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/team/felix-headshot.jpeg -------------------------------------------------------------------------------- /src/assets/team/tom-headshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/team/tom-headshot.jpg -------------------------------------------------------------------------------- /src/assets/testimonials/david-paul.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/testimonials/david-paul.jpg -------------------------------------------------------------------------------- /src/assets/testimonials/esra-kadah.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/testimonials/esra-kadah.png -------------------------------------------------------------------------------- /src/assets/testimonials/jason-rai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/testimonials/jason-rai.png -------------------------------------------------------------------------------- /src/assets/testimonials/renan-araujo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/testimonials/renan-araujo.png -------------------------------------------------------------------------------- /src/assets/testimonials/scott-macdougall.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/testimonials/scott-macdougall.jpeg -------------------------------------------------------------------------------- /src/assets/testimonials/taha-tesser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shorebirdtech/website/8a31d4eb3e3b43ff3dce92cb7aaa65eefbcbd60c/src/assets/testimonials/taha-tesser.png -------------------------------------------------------------------------------- /src/components/blog/blog-callout.tsx: -------------------------------------------------------------------------------- 1 | import { Ellipse } from '@/components/ellipse'; 2 | import { GradientOutlineButton } from '@/components/ui/button'; 3 | import config from '@/config'; 4 | import NewsletterSignupForm from '../newsletter/newsletter-form'; 5 | 6 | function BlogCallout() { 7 | return ( 8 |
9 | 10 | Shorebird allows you update your Flutter apps instantly, over the air. 11 | It takes less than 5 minutes to integrate and complies with Apple and 12 | Google store policies. 13 | 14 | 19 | 20 | Get started 21 | 22 | 23 |
24 | OR 25 |
26 | 27 |
28 | ); 29 | } 30 | 31 | export { BlogCallout }; 32 | -------------------------------------------------------------------------------- /src/components/blog/formatted-date.astro: -------------------------------------------------------------------------------- 1 | --- 2 | interface Props { 3 | date: Date; 4 | } 5 | 6 | const { date } = Astro.props; 7 | --- 8 | 9 | 16 | -------------------------------------------------------------------------------- /src/components/ellipse.tsx: -------------------------------------------------------------------------------- 1 | function Ellipse({ className }: { className?: string }) { 2 | return ( 3 | 11 | 12 | 20 | 21 | 29 | 30 | 31 | 32 | 40 | 41 | 42 | 43 | 44 | 45 | ); 46 | } 47 | 48 | export { Ellipse }; 49 | -------------------------------------------------------------------------------- /src/components/home/blog-overview.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { ArrowRight } from '@phosphor-icons/react'; 3 | import { Button } from '@/components/ui/button'; 4 | import { Card, CardHeader, CardContent } from '@/components/ui/card'; 5 | import { getCollection } from 'astro:content'; 6 | import { Image } from 'astro:assets'; 7 | import { Spacer } from '@/components/ui/spacer'; 8 | import FormattedDate from '@/components/blog/formatted-date.astro'; 9 | 10 | const sortByDate = (a: any, b: any) => 11 | new Date(b.data.date).valueOf() - new Date(a.data.date).valueOf(); 12 | const posts = (await getCollection('blog')).sort(sortByDate).slice(0, 2); 13 | const images = import.meta.glob<{ default: ImageMetadata }>( 14 | '/src/assets/blog/covers/*.{jpeg,jpg,png,gif}' 15 | ); 16 | const postImages = posts.map((post) => { 17 | const cover = post.data.cover; 18 | if (images[`/src/assets/blog/covers/${cover}`]) { 19 | return images[`/src/assets/blog/covers/${cover}`]; 20 | } 21 | throw new Error(`Cover image for blog ${post.data.title} not found`); 22 | }); 23 | --- 24 | 25 |
29 |

Read our blog

30 | 31 |
34 |

35 | Stay up-to-date on all things Shorebird. 36 |

37 | 38 | 41 | 42 |
43 | 44 | 74 |
75 | -------------------------------------------------------------------------------- /src/components/home/brands.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { Marquee } from '@/components/ui/marquee'; 3 | import ApnaKlubLogo from '@/assets/brands/apna-klub.png'; 4 | import ChaiLogo from '@/assets/brands/chai.png'; 5 | import FlashCoLogo from '@/assets/brands/flash-co.png'; 6 | import InvoiceHomeLogo from '@/assets/brands/invoice-home.png'; 7 | import JungleeLogo from '@/assets/brands/junglee.png'; 8 | import KalshiLogo from '@/assets/brands/kalshi.png'; 9 | import KijijiLogo from '@/assets/brands/kijiji.png'; 10 | import PushPressLogo from '@/assets/brands/pushpress.png'; 11 | import SolidesLogo from '@/assets/brands/solides.png'; 12 | import TrackerLogo from '@/assets/brands/tracker.png'; 13 | import TradelingLogo from '@/assets/brands/tradeling.png'; 14 | 15 | const brands = [ 16 | { 17 | name: 'Junglee Games', 18 | url: 'https://www.jungleegames.com', 19 | image: JungleeLogo, 20 | }, 21 | { 22 | name: 'Kijiji', 23 | url: 'https://www.kijiji.ca', 24 | image: KijijiLogo, 25 | }, 26 | { 27 | name: 'Tracker', 28 | url: 'https://tracker.fi', 29 | image: TrackerLogo, 30 | }, 31 | { 32 | name: 'CHAI', 33 | url: 'https://chai-research.com/', 34 | image: ChaiLogo, 35 | }, 36 | { 37 | name: 'Kalshi', 38 | url: 'https://kalshi.com', 39 | image: KalshiLogo, 40 | }, 41 | { 42 | name: 'ApnaKlub', 43 | url: 'https://www.apnaklub.com', 44 | image: ApnaKlubLogo, 45 | }, 46 | { 47 | name: 'Flash.co', 48 | url: 'https://flash.co', 49 | image: FlashCoLogo, 50 | }, 51 | { 52 | name: 'Tradeling', 53 | url: 'https://www.tradeling.com', 54 | image: TradelingLogo, 55 | }, 56 | { 57 | name: 'Invoice Home', 58 | url: 'https://invoicehome.com', 59 | image: InvoiceHomeLogo, 60 | }, 61 | { 62 | name: 'PushPress', 63 | url: 'https://pushpress.com', 64 | image: PushPressLogo, 65 | }, 66 | { 67 | name: 'Solides', 68 | url: 'https://solides.com.br', 69 | image: SolidesLogo, 70 | } 71 | ]; 72 | --- 73 | 74 |
78 |
79 | 80 | { 81 | brands.map((brand) => ( 82 |
86 | 87 | {brand.name} 88 | 89 |
90 | )) 91 | } 92 |
93 |
94 |
95 | -------------------------------------------------------------------------------- /src/components/home/callout.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { Button, GradientOutlineButton } from '@/components/ui/button'; 3 | import { Card } from '@/components/ui/card'; 4 | import { Ellipse } from '@/components/ellipse'; 5 | import config from '@/config'; 6 | --- 7 | 8 |
11 | 14 |

15 | Start shipping fast, today! 16 |

17 |

18 | It takes less than 5 minutes to integrate with your current codebase. 19 |

20 | 34 |
35 |
36 | -------------------------------------------------------------------------------- /src/components/home/faq-overview.tsx: -------------------------------------------------------------------------------- 1 | import { Markdown } from '@/components/ui/markdown'; 2 | import { 3 | Accordion, 4 | AccordionContent, 5 | AccordionItem, 6 | AccordionTrigger, 7 | } from '@/components/ui/accordion'; 8 | 9 | const faqs = [ 10 | { 11 | question: 'Does Shorebird work for existing apps?', 12 | answer: 13 | 'Yes. Shorebird requires no code changes to your Flutter app to adopt. See our [quick start guide](https://docs.shorebird.dev/guides/code_push_quickstart) to get started.', 14 | }, 15 | { 16 | question: 'Does Shorebird comply with Play Store and App Store guidelines?', 17 | answer: 18 | 'Yes. Shorebird has been designed to comply with Play Store and App Store guidelines. Code push is common in the industry, including several other commercial update products from Microsoft [App Center](https://appcenter.ms), [Expo](https://expo.dev), and [Ionic](https://ionic.io/). Refer to the [FAQs](https://docs.shorebird.dev/faq#does-shorebird-comply-with-play-store-guidelines) for more info.', 19 | }, 20 | { 21 | question: 'Can I use this in production?', 22 | answer: 23 | 'Yes! Shorebird is production ready on iOS and Android and has been used in production by thousands of apps since early 2023. We safely deliver millions of patches every month on behalf of our customers.', 24 | }, 25 | { 26 | question: 'Can Shorebird see my source code?', 27 | answer: 28 | 'No. Shorebird never stores or transmits your source code. See our [documentation](https://docs.shorebird.dev/faq/#does-shorebird-store-my-source-code) for more information.', 29 | }, 30 | { 31 | question: 'Can I self-host Shorebird or do you offer on-prem?', 32 | answer: 33 | 'No. Shorebird only offers a centrally hosted solution at this time.', 34 | }, 35 | { 36 | question: 'Where is the roadmap?', 37 | answer: 38 | 'Shorebird is developed entirely in the public, including our [project boards](https://github.com/orgs/shorebirdtech/projects) shows what we are currently working on.', 39 | }, 40 | ]; 41 | 42 | function FaqOverview() { 43 | return ( 44 | 45 | {faqs.map((faq, index) => ( 46 | 47 | {faq.question} 48 | 49 | 50 | 51 | 52 | ))} 53 | 54 | ); 55 | } 56 | 57 | export { FaqOverview }; 58 | -------------------------------------------------------------------------------- /src/components/home/faq.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { ArrowRight } from '@phosphor-icons/react'; 3 | import { FaqOverview } from '@/components/home/faq-overview'; 4 | import { GradientOutlineButton } from '@/components/ui/button'; 5 | --- 6 | 7 |
11 |
12 |
13 |

FAQ

14 | 15 | Check out the top frequently asked questions. For a more comprehensive 16 | list, head to our documentation site. 17 | 18 | 19 | 20 | Go to Docs 21 | 22 | 23 |
24 |
25 | 26 |
27 |
28 |
29 | -------------------------------------------------------------------------------- /src/components/home/features.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import config from '@/config'; 3 | import { GradientOutlineButton } from '@/components/ui/button'; 4 | import { 5 | Card, 6 | CardHeader, 7 | CardTitle, 8 | CardContent, 9 | CardFooter, 10 | } from '@/components/ui/card'; 11 | import { Ellipse } from '@/components/ellipse'; 12 | import { Spacer } from '@/components/ui/spacer'; 13 | import { 14 | ArrowRight, 15 | Lightning, 16 | CheckCircle, 17 | ClockCountdown, 18 | CalendarDots, 19 | Tag, 20 | Queue, 21 | HandPeace, 22 | ArrowCounterClockwise, 23 | } from '@phosphor-icons/react'; 24 | 25 | const features = [ 26 | { 27 | title: 'Ship Faster', 28 | description: 'Get fixes in customers hands on your schedule.', 29 | icon: Lightning, 30 | }, 31 | { 32 | title: 'Roll Back', 33 | description: 'Roll back any updates with the click of a button.', 34 | icon: ArrowCounterClockwise, 35 | }, 36 | { 37 | title: 'Hyper-frequent Updates', 38 | description: 'Ship multiple times a day with confidence.', 39 | icon: ClockCountdown, 40 | }, 41 | { 42 | title: 'Level Playing Field', 43 | description: 44 | 'Provide a consistent experience to all users, regardless of platform.', 45 | icon: CheckCircle, 46 | }, 47 | { 48 | title: 'Seasonal Events', 49 | description: 'Instantly deploy updates during critical times of the year.', 50 | icon: CalendarDots, 51 | }, 52 | { 53 | title: 'White-label', 54 | description: 'Ship to thousands of apps directly from your CI.', 55 | icon: Tag, 56 | }, 57 | { 58 | title: 'Seamless Collaboration', 59 | description: 60 | 'Provide instant access to the latest iterations to all collaborators.', 61 | icon: Queue, 62 | }, 63 | { 64 | title: 'Peace of Mind', 65 | description: 'Rest easy knowing a fix is just a click away.', 66 | icon: HandPeace, 67 | }, 68 | ]; 69 | --- 70 | 71 |
75 |

76 | Give your team superpowers 77 |

78 | 79 |
82 |

83 | Deliver the best possible experience to your users, regardless of 84 | platform. 85 |

86 | 87 | 88 | Learn more 89 | 90 | 91 |
92 | 93 |
94 | { 95 | features.map((feature) => ( 96 | 97 | 98 | 99 | 100 | {feature.title} 101 | {feature.description} 102 | 103 | )) 104 | } 105 | 106 | Get started today! 107 | Setup Shorebird in minutes for free! 108 | 109 | 110 | 111 | Try it now 112 | 113 | 114 | 115 | 116 |
117 |
118 | -------------------------------------------------------------------------------- /src/components/home/for-developers.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { ArrowRight, Check } from '@phosphor-icons/react'; 3 | import { Button, GradientOutlineButton } from '@/components/ui/button'; 4 | import { Image } from 'astro:assets'; 5 | import config from '@/config'; 6 | import QuickFix from '@/assets/features/quick-fix.png'; 7 | import SocialProof from '@/assets/features/social-proof.png'; 8 | --- 9 | 10 |
14 |
15 | Fix bugs quickly 16 |
17 |
18 | Social proof 19 | 2,500+ teams use us 20 |
21 |

For Developers

22 | 23 | With Shorebird, development teams can quickly deploy fixes instead of 24 | waiting for full app releases. 25 | 26 | 52 |
53 |
54 |
55 | -------------------------------------------------------------------------------- /src/components/home/for-teams.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { ArrowRight, Check } from '@phosphor-icons/react'; 3 | import { Button, GradientOutlineButton } from '@/components/ui/button'; 4 | import { Image } from 'astro:assets'; 5 | import config from '@/config'; 6 | import Releases from '@/assets/features/releases.png'; 7 | --- 8 | 9 |
13 |
14 |
15 |

For Teams

16 | 17 | Adding Shorebird to your application allows product teams to make 18 | impactful decisions quickly instead of having to wait for the next app 19 | review cycle. 20 | 21 | 47 |
48 | Patch multiple releases 49 |
50 |
51 | -------------------------------------------------------------------------------- /src/components/home/hero-motion.tsx: -------------------------------------------------------------------------------- 1 | import heroMotion from '@/motion/hero-motion.json'; 2 | import { useLottie } from 'lottie-react'; 3 | import { useEffect, useRef } from 'react'; 4 | 5 | function HeroMotion() { 6 | const ref = useRef(null); 7 | const options = { 8 | animationData: heroMotion, 9 | loop: true, 10 | autoplay: true, 11 | }; 12 | const { View, pause, play } = useLottie(options); 13 | 14 | useEffect(() => { 15 | if (!ref.current) return; 16 | const observer = new IntersectionObserver( 17 | ([entry]) => { 18 | if (entry.isIntersecting) { 19 | play(); 20 | } else { 21 | pause(); 22 | } 23 | }, 24 | { threshold: 0.5 }, 25 | ); 26 | observer.observe(ref.current!); 27 | return () => observer.disconnect(); 28 | }, [ref, play, pause]); 29 | 30 | return {View}; 31 | } 32 | 33 | export { HeroMotion }; 34 | -------------------------------------------------------------------------------- /src/components/home/hero.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { Button, GradientOutlineButton } from '@/components/ui/button'; 3 | import { Ellipse } from '@/components/ellipse'; 4 | import { FlutterLogo } from '@/components/logos/flutter-logo'; 5 | import { HeroMotion } from '@/components/home/hero-motion'; 6 | import { Spacer } from '@/components/ui/spacer'; 7 | import config from '@/config'; 8 | --- 9 | 10 |
14 |
15 |
18 |

19 | Ship fast. 20 |

21 |

22 | Break things. 23 |

24 | 25 |
26 | 27 | Confidently update{' '} 28 | 29 | Flutter apps 30 | 31 | , instantly. 32 | 33 |
34 | 35 | 47 |
48 |
49 | 50 |
51 |
52 |
53 | -------------------------------------------------------------------------------- /src/components/home/pricing-overview.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { PricingCalculator } from '@/components/pricing/pricing-calculator'; 3 | import { PricingPlans } from '@/components/pricing/pricing-plans'; 4 | import { Spacer } from '@/components/ui/spacer'; 5 | --- 6 | 7 |
11 |
12 |

Pay as you grow

13 | 14 |

15 | Deliver instant updates with pricing that scales as you grow. 16 |

17 | 18 | 19 | 20 | 21 |
22 |
23 | -------------------------------------------------------------------------------- /src/components/home/problem.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card'; 3 | import { ClockCountdown, ChartLine, MoneyWavy } from '@phosphor-icons/react'; 4 | import { Spacer } from '@/components/ui/spacer'; 5 | 6 | const problems = [ 7 | { 8 | title: 'App updates are slow', 9 | description: 10 | 'It can take days, or even weeks, to get updates deployed to all users and platforms.', 11 | icon: ClockCountdown, 12 | }, 13 | { 14 | title: 'Releasing is expensive', 15 | description: 16 | 'Automating and coordinating releases takes valuable time away from delivering customer value.', 17 | icon: MoneyWavy, 18 | }, 19 | { 20 | title: 'Deployments are unpredictable', 21 | description: 22 | 'Traditional release processes make it very difficult to estimate when an update will be available to users.', 23 | icon: ChartLine, 24 | }, 25 | ]; 26 | --- 27 | 28 |
32 |
33 |

Shipping updates is hard

34 | 35 |

36 | Building an app is only half the battle. Delivering and coordinating 37 | releases across multiple platforms is a huge source of friction and 38 | complexity. 39 |

40 | 41 |
42 | { 43 | problems.map((problem) => ( 44 | 45 | 46 | 47 | 48 | {problem.title} 49 | {problem.description} 50 | 51 | )) 52 | } 53 |
54 |
55 |
56 | -------------------------------------------------------------------------------- /src/components/home/resources.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card'; 3 | import { Image } from 'astro:assets'; 4 | import { Spacer } from '@/components/ui/spacer'; 5 | import config from '@/config'; 6 | import Discord from '@/assets/resources/discord.png'; 7 | import Shorebird from '@/assets/resources/shorebird.png'; 8 | 9 | const resources = [ 10 | { 11 | image: Shorebird, 12 | title: 'Read the docs', 13 | description: 14 | 'Learn everything you need to get started with Shorebird in just a few minutes from core concepts to detailed tutorials.', 15 | url: config.docsUrl, 16 | }, 17 | { 18 | image: Discord, 19 | title: 'Chat with the community', 20 | description: 21 | "Ask questions, share what you're building, and participate in discussions with the Shorebird community.", 22 | url: config.discordUrl, 23 | }, 24 | ]; 25 | --- 26 | 27 |
31 |

Resources

32 | 33 |

34 | Learn more about Shorebird and chat with the community. 35 |

36 | 37 | 60 |
61 | -------------------------------------------------------------------------------- /src/components/home/solution.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card'; 3 | import { FlutterLogo } from '@/components/logos/flutter-logo'; 4 | import { Image } from 'astro:assets'; 5 | import { Spacer } from '@/components/ui/spacer'; 6 | import AllPlatforms from '@/assets/features/all-platforms.png'; 7 | import AnyCode from '@/assets/features/any-code.png'; 8 | import Compliance from '@/assets/features/compliance.png'; 9 | import Rollback from '@/assets/features/rollback.png'; 10 | 11 | const features = [ 12 | { 13 | image: AllPlatforms, 14 | title: 'Works everywhere Flutter does', 15 | description: 16 | 'Build for users, not platforms. Shorebird allows you to push updates everywhere your users are.', 17 | }, 18 | { 19 | image: AnyCode, 20 | title: 'Change any Dart code', 21 | description: 22 | 'No need to plan ahead. Setup Shorebird in minutes and push updates to any Dart code.', 23 | }, 24 | { 25 | image: Rollback, 26 | title: 'Rollback changes with no impact', 27 | description: 28 | 'Roll changes back instead of rushing the next build through the release process.', 29 | }, 30 | { 31 | image: Compliance, 32 | title: 'Designed for store compliance', 33 | description: 34 | 'Shorebird adheres to all store guidelines to ensure your app is always compliant.', 35 | }, 36 | ]; 37 | --- 38 | 39 |
43 |
46 | 47 | 48 | Built by the same people who built Flutter 49 | 50 |
51 | 52 |

Deliver instant updates

53 | 54 |

55 | Fix critical issues on your schedule by pushing updates directly to users' 56 | devices. 57 |

58 | 59 |
60 | { 61 | features.map((feature) => ( 62 | 63 | 64 | {feature.title} 69 | 70 | 71 | {feature.title} 72 | 73 | 74 | {feature.description} 75 | 76 | 77 | )) 78 | } 79 |
80 |
81 | -------------------------------------------------------------------------------- /src/components/home/success-stories-overview.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { ArrowRight } from '@phosphor-icons/react'; 3 | import { Button } from '@/components/ui/button'; 4 | import { Card, CardHeader, CardContent } from '@/components/ui/card'; 5 | import { getCollection } from 'astro:content'; 6 | import { Image } from 'astro:assets'; 7 | import { Spacer } from '@/components/ui/spacer'; 8 | import FormattedDate from '@/components/blog/formatted-date.astro'; 9 | 10 | const sortByDate = (a: any, b: any) => 11 | new Date(b.data.date).valueOf() - new Date(a.data.date).valueOf(); 12 | const stories = (await getCollection('successStories')).sort(sortByDate).slice(0, 2); 13 | const images = import.meta.glob<{ default: ImageMetadata }>( 14 | '/src/assets/success-stories/covers/*.{jpeg,jpg,png,gif}' 15 | ); 16 | const coverImages = stories.map((story) => { 17 | const cover = story.data.cover; 18 | if (images[`/src/assets/success-stories/covers/${cover}`]) { 19 | return images[`/src/assets/success-stories/covers/${cover}`]; 20 | } 21 | throw new Error(`Cover image for story ${story.data.title} not found`); 22 | }); 23 | --- 24 | 25 |
29 |

Success stories

30 | 31 |
34 |

35 | See how everyone from small teams to global companies are using Shorebird 36 | today. 37 |

38 | 39 | 42 | 43 |
44 | 45 | 72 |
73 | -------------------------------------------------------------------------------- /src/components/home/testimonials.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { Card, CardHeader, CardContent } from '@/components/ui/card'; 3 | import { Image } from 'astro:assets'; 4 | import { Spacer } from '@/components/ui/spacer'; 5 | import JasonRai from '@/assets/testimonials/jason-rai.png'; 6 | import RenanAraujo from '@/assets/testimonials/renan-araujo.png'; 7 | import TahaTesser from '@/assets/testimonials/taha-tesser.png'; 8 | import EsraKadah from '@/assets/testimonials/esra-kadah.png'; 9 | import ScottMacDougall from '@/assets/testimonials/scott-macdougall.jpeg'; 10 | import DavidPaul from '@/assets/testimonials/david-paul.jpg'; 11 | 12 | const testimonials = [ 13 | { 14 | name: 'Jason Rai', 15 | title: 'Head of Frontend Engineering, Kijiji', 16 | quote: 17 | "We use Shorebird at Kijiji on Android and it's been awesome. Working well at a very large scale.", 18 | image: JasonRai, 19 | }, 20 | { 21 | name: 'Renan Araujo', 22 | title: 'Senior Engineer, Superlist', 23 | quote: 24 | 'Shorebird was very useful for distributing updates to my Flame game with over 10k players. Works like a charm.', 25 | image: RenanAraujo, 26 | }, 27 | { 28 | name: 'Taha Tesser', 29 | title: 'Engineer, Codemagic', 30 | quote: 31 | 'Shorebird solves one of the biggest challenges: bringing over-the-air updates instantly to your users. Backed by an amazing team.', 32 | image: TahaTesser, 33 | }, 34 | { 35 | name: 'Esra Kadah', 36 | title: 'Senior Mobile App Developer, Antigua Mobile', 37 | quote: 38 | 'With our client’s app dependency on real-time task management, waiting for app store approvals wasn’t an option. Any downtime could lead to lost revenue for their customers. Shorebird’s over-the-air patches saved us multiple times with critical fixes.', 39 | image: EsraKadah, 40 | }, 41 | { 42 | name: 'Scott MacDougall', 43 | title: 'Head of Engineering, Mobile at Kijiji', 44 | quote: 45 | 'Over time, we have realized that we could Shorebird a fix quickly to all of our users, which made an enormous impact on customer satisfaction. That’s now become a default phrase in our development team, as it’s a great tool to have in our toolbox.', 46 | image: ScottMacDougall, 47 | }, 48 | { 49 | name: 'David Sylvester-Paul', 50 | title: 'CTO at EasySpend', 51 | quote: 52 | 'In the past, we often wondered how other highly rated mobile apps updated their features without forcing users to manually download an update from the store. That curiosity led us to Shorebird, and ever since, we have implemented it in all of our applications.', 53 | image: DavidPaul, 54 | }, 55 | ]; 56 | --- 57 | 58 |
62 |
63 |

Testimonials

64 | 65 |

66 | See what the community has to say about Shorebird. 67 |

68 | 69 |
70 | { 71 | testimonials.map((testimonial, index) => { 72 | return ( 73 | 74 | 75 |
76 | {testimonial.name} 81 |
82 |

{testimonial.name}

83 |

{testimonial.title}

84 |
85 |
86 |
87 | {testimonial.quote} 88 |
89 | ); 90 | }) 91 | } 92 |
93 |
94 |
95 | -------------------------------------------------------------------------------- /src/components/logos/discord-logo.tsx: -------------------------------------------------------------------------------- 1 | function DiscordLogo({ className }: { className?: string }) { 2 | return ( 3 | 11 | 12 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | ); 24 | } 25 | 26 | export { DiscordLogo }; 27 | -------------------------------------------------------------------------------- /src/components/logos/flutter-logo.tsx: -------------------------------------------------------------------------------- 1 | function FlutterLogo({ className }: { className?: string }) { 2 | return ( 3 | 12 | 16 | 20 | 24 | 28 | 32 | 36 | 37 | 43 | 44 | 45 | 53 | 54 | 55 | 56 | 61 | 62 | 63 | ); 64 | } 65 | 66 | export { FlutterLogo }; 67 | -------------------------------------------------------------------------------- /src/components/logos/github-logo.tsx: -------------------------------------------------------------------------------- 1 | function GitHubLogo({ className }: { className?: string }) { 2 | return ( 3 | 11 | 12 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | ); 24 | } 25 | 26 | export { GitHubLogo }; 27 | -------------------------------------------------------------------------------- /src/components/logos/linkedin-logo.tsx: -------------------------------------------------------------------------------- 1 | function LinkedInLogo({ className }: { className?: string }) { 2 | return ( 3 | 11 | 17 | 23 | 24 | ); 25 | } 26 | 27 | export { LinkedInLogo }; 28 | -------------------------------------------------------------------------------- /src/components/logos/twitter-logo.tsx: -------------------------------------------------------------------------------- 1 | function TwitterLogo({ className }: { className?: string }) { 2 | return ( 3 | 11 | 15 | 16 | ); 17 | } 18 | 19 | export { TwitterLogo }; 20 | -------------------------------------------------------------------------------- /src/components/pricing/pricing-calculator.tsx: -------------------------------------------------------------------------------- 1 | import { Button } from '@/components/ui/button'; 2 | import { Card, CardContent, CardHeader } from '@/components/ui/card'; 3 | import { Slider } from '@/components/ui/slider'; 4 | import { ArrowRight } from '@phosphor-icons/react'; 5 | import React from 'react'; 6 | 7 | const clamp = (n: number, min: number, max: number) => 8 | Math.min(Math.max(n, min), max); 9 | 10 | function PricingCalculator({ hideCTA }: { hideCTA?: boolean }) { 11 | const [activeUsers, setActiveUsers] = React.useState(5000); 12 | 13 | const calculatePrice = () => { 14 | const totalPatches = 1 * activeUsers; // Assume 1 patch per active user 15 | const plan = totalPatches > 5000 ? 'Pro' : 'Free'; 16 | const platformFee = totalPatches > 5000 ? 20 : 0; 17 | const includedPatchInstalls = plan === 'Pro' ? 50000 : 5000; 18 | const overages = clamp( 19 | Math.ceil((totalPatches - includedPatchInstalls) * (1 / 2500)), 20 | 0, 21 | Infinity, 22 | ); 23 | 24 | return { 25 | total: 26 | activeUsers > 2000000 27 | ? null 28 | : `$${(platformFee + overages).toLocaleString()}`, 29 | }; 30 | }; 31 | const pricing = calculatePrice(); 32 | const monthlyActiveUsers = 33 | activeUsers > 2000000 ? '2,000,000+' : activeUsers.toLocaleString(); 34 | 35 | return ( 36 | 37 | 38 |
39 |
40 |

Cost per patch

41 |

42 | Estimate the cost to send a patch to your users. 43 |

44 |
45 | {!hideCTA && ( 46 | 47 | 51 | 52 | )} 53 |
54 |
55 | 56 |
57 |
58 |

Users

59 |

60 | {monthlyActiveUsers} 61 |

62 |
63 |
64 |

Estimated Cost

65 |

66 | {pricing.total ?? 'Contact Us '} 67 |

68 |
69 |
70 |
71 | setActiveUsers(value as number)} 77 | /> 78 |
79 |
80 |

81 | *Prices are quoted in USD and sold as "patch installs per month", 82 | reflecting successful installs of a given patch. For example, 1 83 | patch pushed to 10 devices is 10 installs. 2 patches pushed to 5 84 | devices is also 10 installs. 85 |

86 |
87 |
88 |
89 | ); 90 | } 91 | export { PricingCalculator }; 92 | -------------------------------------------------------------------------------- /src/components/pricing/pricing-details.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import config from '@/config'; 3 | import { GradientOutlineButton } from '@/components/ui/button'; 4 | import { PricingCalculator } from '@/components/pricing/pricing-calculator'; 5 | import { PricingPlans } from '@/components/pricing/pricing-plans'; 6 | import { PricingFaq } from '@/components/pricing/pricing-faq'; 7 | import { Spacer } from '@/components/ui/spacer'; 8 | import { ArrowRight } from '@phosphor-icons/react'; 9 | --- 10 | 11 |
14 |
15 |

16 | Pay as you grow 17 |

18 | 19 |

20 | Deliver instant updates with pricing that scales as you grow. 21 |

22 | 23 | 24 | 25 | 26 |
27 |
28 |
29 |

FAQ

30 | 31 | Check out the top frequently asked questions regarding pricing. If 32 | you still have questions, please contact us. 33 | 34 | 35 | 36 | Contact us 37 | 38 | 39 |
40 |
41 | 42 |
43 |
44 |
45 |
46 |
47 | -------------------------------------------------------------------------------- /src/components/pricing/pricing-faq.tsx: -------------------------------------------------------------------------------- 1 | import { Markdown } from '@/components/ui/markdown'; 2 | import { 3 | Accordion, 4 | AccordionContent, 5 | AccordionItem, 6 | AccordionTrigger, 7 | } from '@/components/ui/accordion'; 8 | 9 | const faqs = [ 10 | { 11 | question: 'How many patch installs will I use?', 12 | answer: 13 | 'You are only billed for successful patch installs. \ 14 | This occurs when the user opens your app with the new patch installed. \ 15 | A rule of thumb is number of patches per month times number of monthly active users. \ 16 | If you have 1000 MAU and you ship 4 patches per month, you will likely use about 4000 patch installs.', 17 | }, 18 | { 19 | question: 'Do you offer discounts?', 20 | answer: 21 | 'We offer committed use discounts for customers who commit to a certain number of patch installs per month. We offer committed usage discounts starting at 2.5M patches per month.', 22 | }, 23 | { 24 | question: 'How much are your Enterprise plans?', 25 | answer: 26 | 'We offer our enterprise services starting at $2,000 per month. Below that level we recommend our self-service plans.', 27 | }, 28 | { 29 | question: 'Do patch installs expire?', 30 | answer: 31 | 'Yes, patch install credits expire at the end of each billing period, typically one month. We do not offer rollover credits.', 32 | }, 33 | { 34 | question: 'Can I pay annually?', 35 | answer: 'Yes, all paid plans support annual or monthly billing.', 36 | }, 37 | { 38 | question: 'What payment methods do you accept?', 39 | answer: 40 | 'We accept any method of payment Stripe accepts in your region. Enterprise customers can also pay by invoice.', 41 | }, 42 | { 43 | question: 'When am I charged for patch installs?', 44 | answer: 45 | 'At the start of each billing period, you are billed for your pre-paid patches. \ 46 | In the case of a Pro plan, this includes 50,000 pre-paid patch installs. \ 47 | "Overage" patch installs are billed at the end of each billing period. \ 48 | The initial invoice (month 1) will only include the prepaid patches, however successive months will include \ 49 | overage bills as well. For example, if you are using the Pro plan \ 50 | (includes 50,000 pre-paid patches), and you use 100,000 patch installs each month, \ 51 | you will be charged $20 when you sign up, and then $40 at the beginning of month 2 \ 52 | ($20 for the 50,000 overage, and $20 for Month 2\'s Pro plan). \ 53 | You can always check the status of your account and billing at \ 54 | https://console.shorebird.dev/account.', 55 | }, 56 | ]; 57 | 58 | function PricingFaq() { 59 | return ( 60 | 61 | {faqs.map((faq, index) => ( 62 | 63 | {faq.question} 64 | 65 | 66 | 67 | 68 | ))} 69 | 70 | ); 71 | } 72 | 73 | export { PricingFaq }; 74 | -------------------------------------------------------------------------------- /src/components/scroll-to-top-button.tsx: -------------------------------------------------------------------------------- 1 | import { Button } from '@/components/ui/button'; 2 | import { CaretUp } from '@phosphor-icons/react'; 3 | import { useEffect, useState } from 'react'; 4 | 5 | function ScrollToTopButton() { 6 | const [isVisible, setIsVisible] = useState(false); 7 | 8 | useEffect(() => { 9 | window.addEventListener('scroll', toggleVisible); 10 | }, []); 11 | 12 | const toggleVisible = () => { 13 | const scrolled = document.documentElement.scrollTop; 14 | if (scrolled > 300) { 15 | setIsVisible(true); 16 | } else if (scrolled <= 300) { 17 | setIsVisible(false); 18 | } 19 | }; 20 | 21 | const scrollToTop = () => { 22 | window.scrollTo({ 23 | top: 0, 24 | behavior: 'smooth', 25 | }); 26 | }; 27 | 28 | return ( 29 | <> 30 | {isVisible && ( 31 | 39 | )} 40 | 41 | ); 42 | } 43 | 44 | export { ScrollToTopButton }; 45 | -------------------------------------------------------------------------------- /src/components/ui/accordion.tsx: -------------------------------------------------------------------------------- 1 | import * as AccordionPrimitive from '@radix-ui/react-accordion'; 2 | import { ChevronDownIcon } from 'lucide-react'; 3 | import * as React from 'react'; 4 | 5 | import { cn } from '@/lib/utils'; 6 | 7 | function Accordion({ 8 | ...props 9 | }: React.ComponentProps) { 10 | return ; 11 | } 12 | 13 | function AccordionItem({ 14 | className, 15 | ...props 16 | }: React.ComponentProps) { 17 | return ( 18 | 23 | ); 24 | } 25 | 26 | function AccordionTrigger({ 27 | className, 28 | children, 29 | ...props 30 | }: React.ComponentProps) { 31 | return ( 32 | 33 | svg]:rotate-180', 37 | className, 38 | )} 39 | {...props} 40 | > 41 | {children} 42 | 43 | 44 | 45 | ); 46 | } 47 | 48 | function AccordionContent({ 49 | className, 50 | children, 51 | ...props 52 | }: React.ComponentProps) { 53 | return ( 54 | 59 |
{children}
60 |
61 | ); 62 | } 63 | 64 | export { Accordion, AccordionContent, AccordionItem, AccordionTrigger }; 65 | -------------------------------------------------------------------------------- /src/components/ui/button.tsx: -------------------------------------------------------------------------------- 1 | import { Slot } from '@radix-ui/react-slot'; 2 | import { cva, type VariantProps } from 'class-variance-authority'; 3 | import * as React from 'react'; 4 | 5 | import { cn } from '@/lib/utils'; 6 | 7 | const buttonVariants = cva( 8 | "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive", 9 | { 10 | variants: { 11 | variant: { 12 | default: 'bg-primary text-button-primary-text shadow-xs', 13 | outline: 14 | 'text-button-primary-text border border-input border-border-1 rounded-full bg-background hover:shadow-xs hover:bg-foreground/10 hover:border-foreground/40', 15 | secondary: 16 | 'bg-secondary text-button-secondary-text shadow-xs hover:bg-secondary/80', 17 | ghost: 'text-button-primary-text', 18 | link: 'text-primary underline-offset-4 hover:underline', 19 | }, 20 | size: { 21 | default: 'h-12 px-4 py-2', 22 | sm: 'h-10 rounded-full gap-1.5 px-3', 23 | lg: 'h-15 rounded-md px-6 has-[>svg]:px-4', 24 | icon: 'size-12 rounded-full p-1', 25 | }, 26 | }, 27 | defaultVariants: { 28 | variant: 'default', 29 | size: 'default', 30 | }, 31 | }, 32 | ); 33 | 34 | function GradientOutlineButton({ 35 | className, 36 | children, 37 | }: React.PropsWithChildren<{ className?: string }>) { 38 | return ( 39 |
40 | 49 |
50 | ); 51 | } 52 | 53 | function Button({ 54 | className, 55 | variant, 56 | size, 57 | asChild = false, 58 | ...props 59 | }: React.ComponentProps<'button'> & 60 | VariantProps & { 61 | asChild?: boolean; 62 | }) { 63 | const Comp = asChild ? Slot : 'button'; 64 | 65 | return ( 66 | 71 | ); 72 | } 73 | 74 | export { Button, buttonVariants, GradientOutlineButton }; 75 | -------------------------------------------------------------------------------- /src/components/ui/card.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | import { cn } from '@/lib/utils'; 4 | 5 | function Card({ className, ...props }: React.ComponentProps<'div'>) { 6 | return ( 7 |
15 | ); 16 | } 17 | 18 | function CardHeader({ className, ...props }: React.ComponentProps<'div'>) { 19 | return ( 20 |
25 | ); 26 | } 27 | 28 | function CardTitle({ className, ...props }: React.ComponentProps<'div'>) { 29 | return ( 30 |
35 | ); 36 | } 37 | 38 | function CardDescription({ className, ...props }: React.ComponentProps<'div'>) { 39 | return ( 40 |
45 | ); 46 | } 47 | 48 | function CardContent({ className, ...props }: React.ComponentProps<'div'>) { 49 | return ( 50 |
55 | ); 56 | } 57 | 58 | function CardFooter({ className, ...props }: React.ComponentProps<'div'>) { 59 | return ( 60 |
65 | ); 66 | } 67 | 68 | export { 69 | Card, 70 | CardContent, 71 | CardDescription, 72 | CardFooter, 73 | CardHeader, 74 | CardTitle, 75 | }; 76 | -------------------------------------------------------------------------------- /src/components/ui/footer.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { Button } from '@/components/ui/button'; 3 | import { DiscordLogo } from '@/components/logos/discord-logo'; 4 | import { GitHubLogo } from '@/components/logos/github-logo'; 5 | import { LinkedInLogo } from '@/components/logos/linkedin-logo'; 6 | import { LogoFull } from '@/components/logos/logo-full'; 7 | import { Spacer } from '@/components/ui/spacer'; 8 | import { TwitterLogo } from '@/components/logos/twitter-logo'; 9 | import config from '@/config'; 10 | --- 11 | 12 | 95 | -------------------------------------------------------------------------------- /src/components/ui/input.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | import { cn } from '@/lib/utils'; 4 | 5 | function Input({ className, type, ...props }: React.ComponentProps<'input'>) { 6 | return ( 7 | 18 | ); 19 | } 20 | 21 | export { Input }; 22 | -------------------------------------------------------------------------------- /src/components/ui/markdown.tsx: -------------------------------------------------------------------------------- 1 | import ReactMarkdown from 'react-markdown'; 2 | 3 | interface MarkdownProps { 4 | content: string; 5 | } 6 | 7 | function Markdown({ content }: MarkdownProps) { 8 | return {content}; 9 | } 10 | 11 | export { Markdown }; 12 | -------------------------------------------------------------------------------- /src/components/ui/marquee.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from '@/lib/utils'; 2 | import '@/styles/global.css'; 3 | import type { HTMLAttributes, ReactNode } from 'react'; 4 | 5 | export type MarqueeProps = HTMLAttributes & { 6 | children: ReactNode; 7 | direction?: 'left' | 'up'; 8 | pauseOnHover?: boolean; 9 | reverse?: boolean; 10 | fade?: boolean; 11 | innerClassName?: string; 12 | numberOfCopies?: number; 13 | }; 14 | 15 | export function Marquee({ 16 | children, 17 | direction = 'left', 18 | pauseOnHover = false, 19 | reverse = false, 20 | fade = false, 21 | className, 22 | innerClassName, 23 | numberOfCopies = 2, 24 | ...rest 25 | }: MarqueeProps) { 26 | return ( 27 |
47 | {Array(numberOfCopies) 48 | .fill(0) 49 | .map((_, i) => ( 50 |
62 | {children} 63 |
64 | ))} 65 |
66 | ); 67 | } 68 | -------------------------------------------------------------------------------- /src/components/ui/slider.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from '@/lib/utils'; 2 | import { Slider as BaseSlider } from '@base-ui-components/react/slider'; 3 | 4 | interface SliderProps { 5 | className?: string; 6 | min: number; 7 | max: number; 8 | step: number; 9 | defaultValue?: number; 10 | value?: number; 11 | onValueChange?: ( 12 | value: number | number[], 13 | event: Event, 14 | activeThumbIndex: number, 15 | ) => void; 16 | } 17 | 18 | function Slider({ 19 | className, 20 | min, 21 | max, 22 | step, 23 | defaultValue, 24 | value, 25 | onValueChange, 26 | }: SliderProps) { 27 | return ( 28 | 36 | 42 | 43 | 48 | 49 | 50 | 51 | 52 | ); 53 | } 54 | export { Slider }; 55 | -------------------------------------------------------------------------------- /src/components/ui/spacer.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from '@/lib/utils.ts'; 2 | 3 | function Spacer({ className }: { className?: string }) { 4 | return
; 5 | } 6 | 7 | export { Spacer }; 8 | -------------------------------------------------------------------------------- /src/components/ui/table.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | import { cn } from '@/lib/utils'; 4 | 5 | function Table({ className, ...props }: React.ComponentProps<'table'>) { 6 | return ( 7 |
11 | 16 | 17 | ); 18 | } 19 | 20 | function TableHeader({ className, ...props }: React.ComponentProps<'thead'>) { 21 | return ( 22 | 27 | ); 28 | } 29 | 30 | function TableBody({ className, ...props }: React.ComponentProps<'tbody'>) { 31 | return ( 32 | 37 | ); 38 | } 39 | 40 | function TableFooter({ className, ...props }: React.ComponentProps<'tfoot'>) { 41 | return ( 42 | tr]:last:border-b-0', 46 | className, 47 | )} 48 | {...props} 49 | /> 50 | ); 51 | } 52 | 53 | function TableRow({ className, ...props }: React.ComponentProps<'tr'>) { 54 | return ( 55 | 63 | ); 64 | } 65 | 66 | function TableHead({ className, ...props }: React.ComponentProps<'th'>) { 67 | return ( 68 |
[role=checkbox]]:translate-y-[2px]', 72 | className, 73 | )} 74 | {...props} 75 | /> 76 | ); 77 | } 78 | 79 | function TableCell({ className, ...props }: React.ComponentProps<'td'>) { 80 | return ( 81 | [role=checkbox]]:translate-y-[2px]', 85 | className, 86 | )} 87 | {...props} 88 | /> 89 | ); 90 | } 91 | 92 | function TableCaption({ 93 | className, 94 | ...props 95 | }: React.ComponentProps<'caption'>) { 96 | return ( 97 |
102 | ); 103 | } 104 | 105 | export { 106 | Table, 107 | TableBody, 108 | TableCaption, 109 | TableCell, 110 | TableFooter, 111 | TableHead, 112 | TableHeader, 113 | TableRow, 114 | }; 115 | -------------------------------------------------------------------------------- /src/config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | app: 'Shorebird', 3 | tagline: 4 | 'Over the air updates for Flutter. Confidently update Flutter apps instantly.', 5 | discordUrl: 'https://discord.gg/shorebird', 6 | githubUrl: 'https://github.com/shorebirdtech/shorebird', 7 | twitterUrl: 'https://twitter.com/shorebirddev', 8 | linkedInUrl: 'https://www.linkedin.com/company/shorebirddev', 9 | newsletterSubscriptionUrl: 'https://shorebird.dev/newsletter-signup', 10 | consoleUrl: 'https://console.shorebird.dev', 11 | docsUrl: 'https://docs.shorebird.dev', 12 | monthlyProPlanCheckoutUrl: 13 | 'https://console.shorebird.dev/subscriptions/create?plan=pro&billed=monthly', 14 | yearlyProPlanCheckoutUrl: 15 | 'https://console.shorebird.dev/subscriptions/create?plan=pro&billed=yearly', 16 | monthlyBusinessPlanCheckoutUrl: 17 | 'https://console.shorebird.dev/subscriptions/create?plan=business&billed=monthly', 18 | yearlyBusinessPlanCheckoutUrl: 19 | 'https://console.shorebird.dev/subscriptions/create?plan=business&billed=yearly', 20 | contactSales: 'https://calendly.com/d/cmtb-j7m-qpb/shorebird-sales', 21 | contactEmail: 'contact@shorebird.dev', 22 | }; 23 | -------------------------------------------------------------------------------- /src/content/blog/1.0.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Shorebird 1.0 3 | author: shorebirdtech 4 | description: 5 | Announcing Shorebird Code Push 1.0 including stable support for iOS and how to 6 | get started. 7 | date: 2024-04-08 8 | cover: '1.0-cover.png' 9 | slug: '1.0' 10 | --- 11 | 12 | We’re excited to announce Shorebird Code Push 1.0, including stable support for 13 | iOS! 14 | 15 | ## 🐦 What is Shorebird? 16 | 17 | Shorebird allows you to update your Flutter apps instantly over the air, 18 | deploying fixes directly to end users' devices. Shorebird can be 19 | [integrated into your app](https://docs.shorebird.dev) in under 5 minutes and 20 | requires no code changes. With Shorebird, you can update any Dart code in your 21 | app instantly. 22 | 23 | Shorebird is built to comply with 24 | [Apple](https://docs.shorebird.dev/faq#does-shorebird-comply-with-app-store-guidelines) 25 | and 26 | [Google](https://docs.shorebird.dev/faq#does-shorebird-comply-with-play-store-guidelines) 27 | store policies without sacrificing performance (even after patching). 28 | 29 | Shorebird is free to use for small apps and offers plans that scale as your app 30 | grows. 31 | 32 | ## 🚀 Get Started 33 | 34 | Get started now with our 35 | [Quick Start Guide](https://docs.shorebird.dev/guides/code_push_quickstart)! 36 | 37 | iOS stable requires the latest version of Shorebird CLI (1.0.0) and the latest 38 | stable version of Flutter (3.19.5). Known issues are tracked on our 39 | [status page](https://docs.shorebird.dev/status). 40 | 41 | Code is available on [GitHub](https://github.com/shorebirdtech/shorebird). 42 | 43 | See you on [Discord](https://discord.gg/shorebird) 👋 44 | 45 | Your Shorebird Team 46 | -------------------------------------------------------------------------------- /src/content/blog/brand-refresh.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Website Redesign & Brand Refresh 3 | author: felangel 4 | description: Announcing our redesigned site and refreshed branding. 5 | date: 2025-03-06 6 | cover: 'brand-refresh-cover.png' 7 | --- 8 | 9 | 10 | 11 | Shorebird has been around for just over 2 years and we felt it was time for a 12 | much-needed brand refresh! 13 | 14 | ### Redesigned Website 15 | 16 | We're super excited to announce the next iteration of 17 | [shorebird.dev](https://shorebird.dev) 🥳 18 | 19 | ![New Site Design](../../assets/blog/brand-refresh/new-site-design.png) 20 | 21 | Our previous site was very minimal and tailored specifically for developers. One 22 | of our main goals for the site redesign was to clearly (and visually) 23 | communicate the value of Shorebird's solutions to both developers and 24 | non-technical folks. 25 | 26 | ### Brand Refresh 27 | 28 | We also took this as an opportunity to refresh our logo. Our goal was to polish 29 | and simplify where possible while still maintaining the cute, playful sandpiper. 30 | 31 | _Fun Fact: Did you know the name Shorebird is the name of the street on which 32 | Flutter was created?_ 33 | 34 | ![Refreshed Logo](../../assets/blog/brand-refresh/refreshed-logo.png) _Old Logo 35 | (left), Refreshed Logo (right)_ 36 | 37 | We also revisited and adjusted our core brand assets including our typography, 38 | color palette, and more. 39 | 40 | ![Color Palette](../../assets/blog/brand-refresh/color-palette.png) 41 | 42 | ### Conclusion 43 | 44 | With a primary focus on making Shorebird more accessible to technical and 45 | non-technical folks alike, this redesign includes: 46 | 47 | - Updated Typography 48 | - Updated Color Palette 49 | - Refreshed Logo 50 | - Redesigned Website 51 | - Social assets 52 | - And more... 53 | 54 | We'd love to hear your thoughts on the refresh! If you'd like to give feedback, 55 | ask questions, or just say hi you can reach us on 56 | [Discord](https://discord.gg/shorebird). 57 | 58 | A huge thank you to [Enuma](https://www.enuma-collective.com) for helping make 59 | this redesign a reality 💙 60 | -------------------------------------------------------------------------------- /src/content/blog/buy-dont-build.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: The Smarter Way to Ship Flutter Updates 3 | author: tomarra 4 | description: 5 | Learning from enterprise players that custom code deployment systems are 6 | valuable but a lot to maintain. 7 | date: 2025-02-24 8 | cover: buy-dont-build-cover.png 9 | --- 10 | 11 | 12 | 13 | Sometimes, the best engineering solution isn’t to build—it’s to buy. 14 | 15 | That’s a lesson many companies learn the hard way when tackling the problem of 16 | mobile app updates. For companies that rely on fast iteration cycles, the 17 | limitations of the App Store and Google Play’s release process can be a major 18 | bottleneck. Engineering teams often invest months—or even years—developing 19 | internal solutions to push updates dynamically, only to find that maintaining 20 | these systems is just as challenging as building them. But what if you didn’t 21 | have to build your own solution? What if you could buy it? 22 | 23 | ## Learning from Nubank: A Case for Dynamic Updates 24 | 25 | This idea crystallized for me while listening to 26 | [Build to Succeed](https://verygood.ventures/podcasts), a podcast episode 27 | featuring [Thiago Ghisi from Nubank](https://www.linkedin.com/in/thiagoghisi/). 28 | [Nubank](https://nubank.com.br/en/), one of the largest fintech companies in the 29 | world, serves over 100 million customers with its mobile-first platform and 30 | [has been using Flutter](https://building.nubank.com.br/scaling-with-flutter/) 31 | for a number of years. Given the scale and pace at which Nubank operates, they 32 | needed a way to bypass the friction of app store release cycles. Their solution? 33 | A sophisticated server-driven UI framework that allowed them to push UI updates 34 | without requiring users to download a new version of the app. 35 | 36 | During this episode Thiago described how this approach emerged as a necessity 37 | rather than a luxury. With hundreds of screens and a mobile engineering team 38 | struggling to keep up with demand, they needed a scalable way to ship updates 39 | multiple times a day. By moving logic to the backend, Nubank could iterate 40 | faster, conduct A/B tests more effectively, and reduce dependency on mobile 41 | engineers for UI changes. 42 | 43 | But this approach wasn’t built overnight. It took years of iteration, countless 44 | challenges, and a significant engineering investment to get right. And it’s a 45 | lesson for other companies—one that Shorebird is helping other businesses avoid. 46 | 47 | ## Shorebird: App Updates Without the Pain 48 | 49 | Shorebird provides a ready-made solution for companies looking to achieve what 50 | Nubank did – over the air updates – without the time, effort, and cost of 51 | building it from scratch. Our instant update technology allows mobile teams to 52 | update their apps instantly, without waiting for app store approvals or worrying 53 | about fragmented user adoption. 54 | 55 | At Shorebird, we believe in empowering businesses to be successful with Flutter. 56 | Our mission is to make multi-platform development the default way all developers 57 | build software. We understand that in today’s fast-paced world, companies need 58 | the ability to iterate quickly and deploy changes seamlessly. That’s why we’ve 59 | built Shorebird—to remove the barriers of app store releases and allow 60 | businesses to focus on what matters most: delivering exceptional user 61 | experiences. 62 | 63 | If your engineering team is considering building an internal code push system, 64 | ask yourself: is this really the best use of your resources? Nubank’s story 65 | shows that while the benefits of dynamic updates are clear, the road to building 66 | them yourself is long and complex. 67 | 68 | With Shorebird, you can skip the years of development and get straight to the 69 | benefits. Why build when you can buy? 70 | -------------------------------------------------------------------------------- /src/content/blog/custom-tracks.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Custom Update Tracks 3 | author: bryanoltman 4 | description: Announcing the ability to create custom tracks 5 | date: 2025-05-30 6 | cover: custom-tracks-cover.png 7 | --- 8 | 9 | Shorebird now supports custom update tracks! 10 | 11 | Shorebird has long supported “staging” and “beta” environments for testing your 12 | patches before deploying them to users. However, now we have added the ability 13 | to create an unlimited number of tracks with custom names. 14 | 15 | Shorebird does not collect any information about your users. As a result of our 16 | privacy-forward design, Shorebird has no ability to provide things like region- 17 | or group-based rollouts of patches, A/B testing, etc. out-of-the-box. However, 18 | we provide a rich API set to enable you to implement all of these from within 19 | your own apps. Previously, these APIs were limited to operating on a fixed 20 | number of tracks (“staging”, “beta”, and “stable”), but now you can use an 21 | arbitrary number of tracks and push separate patches to each one should you 22 | wish. This can allow you to roll out updates with as much precision as you would 23 | like. 24 | 25 | To use these new features, first ensure you’re using package:shorebird_code_push 26 | version 2.0.4 or later. Update your pubspec: 27 | 28 | ```yaml 29 | dependencies: 30 | shorebird_code_push: ^2.0.4 31 | ``` 32 | 33 | Once that’s done, `Updater.checkForUpdate` now can receive any string as an 34 | UpdateTrack. Check out our 35 | [package docs](https://pub.dev/documentation/shorebird_code_push/2.0.4/shorebird_code_push/UpdateTrack-extension-type.html) 36 | for more details on this. 37 | 38 | For example if your organization has a longer multi-track approval process, or 39 | your own custom update process you might need more tracks: 40 | 41 | ```dart 42 | final track; 43 | if (user.isQa) { 44 | track = UpdateTrack('qa'); 45 | } else if (user.isDev) { 46 | track = UpdateTrack('dev'); 47 | } else if (user.isDesigner) { 48 | track = UpdateTrack('down-stream-test'); 49 | } else { 50 | track = UpdateTrack.stable; 51 | } 52 | 53 | updater.checkForUpdate(track:track); 54 | ``` 55 | 56 | Or for example if your app is required to change or disable a behavior within a 57 | specific region (e.g. as part of legal or compliance changes): 58 | 59 | ```dart 60 | final UpdateTrack updateTrack; 61 | if (user.requiresLegalUpdates) { 62 | updateTrack = UpdateTrack('legal-update'); 63 | } else { 64 | updateTrack = UpdateTrack.stable; 65 | } 66 | ``` 67 | 68 | Note that the name “stable” is still special in the sense that it is the 69 | default. If you call updater.checkForUpdate() without a track argument, it will 70 | default to “stable”. There is currently no way to change the default track used 71 | by our C++ “auto_updater” code, however when the auto_updater is disabled, you 72 | can use whatever default track you like when calling checkForUpdate. 73 | 74 | These new features are supported in every version of Flutter that Shorebird 75 | supports, and because this update only includes Dart changes, it's even possible 76 | to even to start using these new features via a patch. 77 | -------------------------------------------------------------------------------- /src/content/blog/dart-3.5.0.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Surviving the upgrade to Dart 3.5.0 3 | author: bryanoltman 4 | description: Troubleshooting when upgrading to Dart 3.5.0 5 | date: 2024-08-16 6 | cover: dart-3.5-cover.png 7 | slug: 'dart-3.5.0' 8 | --- 9 | 10 | One of the big features of 11 | [Flutter 3.24.0](https://medium.com/flutter/whats-new-in-flutter-3-24-6c040f87d1e4) 12 | is an upgrade to Dart 3.5.0, which comes with a whole bunch of 13 | [nice changes](https://medium.com/dartlang/dart-3-5-6ca36259fa2f). 14 | Unfortunately, like all software releases, it also came with some bugs. 15 | 16 | We encountered some bugs when upgrading our projects at Shorebird and have 17 | listed the problems and workarounds we found here: 18 | 19 | ## ../.pub-cache/hosted/pub.dev/win32-5.5.0/lib/src/guid.dart:32:9: Error: Type 'UnmodifiableUint8ListView' not found. 20 | 21 | We were [not](https://github.com/jonataslaw/get_cli/issues/263) 22 | [alone](https://github.com/orgs/codemagic-ci-cd/discussions/2678) in seeing this 23 | issue. Fortunately, the fix is fairly straightforward: 24 | 25 | ```sh 26 | flutter pub cache clean 27 | flutter pub upgrade 28 | ``` 29 | 30 | If you track your `pubspec.lock` file in source control (tip: you should!), you 31 | should see that the `win32` dependency has been upgraded, and you should now be 32 | able to build. 33 | 34 | ## None of your analysis warnings show up in Visual Studio Code. 35 | 36 | If: 37 | 38 | 1. Your `pubspec.yaml` file is not at the root of your repo (or "workspace") 39 | 2. Your `analysis_options.yaml` file uses an "import" to pull in rules from 40 | another file (the default Flutter and Dart templates include `package:lints` 41 | or `package:flutter_lints`). 42 | 43 | This can be worked around by adding a `pubspec.yaml` at the root of your 44 | checkout/workspace. This is what we've used: 45 | 46 | ```yaml 47 | # This file is a workaround for https://github.com/dart-lang/sdk/issues/56047 48 | name: your_project_name_here 49 | environment: 50 | sdk: ^3.5.0 51 | dev_dependencies: 52 | very_good_analysis: ^6.0.0 53 | ``` 54 | 55 | The above example uses 56 | [very_good_analysis](https://pub.dev/packages/very_good_analysis) (which is the 57 | lints package we use at [Shorebird](https://shorebird.dev)), but you can easily 58 | change the above to use [package:lints](https://pub.dev/packages/lints) or 59 | [package:flutter_lints](https://pub.dev/packages/flutter_lints) or whatever 60 | analysis imports you depend on. 61 | 62 | You can test that this is working by introducing an error in one of your 63 | packages not at the root of your repo and you should once again see that error 64 | in the "Problems" tab of Visual Studio Code. 65 | 66 | ## Conclusion 67 | 68 | Did you have trouble with Dart 3.5.0? Did we miss something? We'd love to hear 69 | from you. Reach out via [email](mailto:contact@shorebird.dev) or 70 | [Discord](https://discord.gg/shorebird) anytime. 71 | -------------------------------------------------------------------------------- /src/content/blog/dart-macros.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: On Focus and Dart Macros 3 | author: eseidel 4 | description: Reacting to Google's decision to cancel Dart's "macros" feature 5 | date: 2025-01-29 6 | cover: dart-macros-cover.png 7 | --- 8 | 9 | Brace yourselves. We may be in for another round of “Flutter is dying” and “Dart 10 | is dying” hot takes across the blog-o-sphere. 11 | 12 | But again, maybe at this point I’m used to it? I co-founded the Flutter project 13 | at Google in 2014 and led the Flutter (and later Dart) teams at Google until 14 | 2022 when I left to found this company, Shorebird. Shorebird sells products to 15 | teams using Flutter and I remain deeply involved and invested in Flutter and 16 | Dart's success. Flutter has been “dying” or “about to be canceled by Google” 17 | since we started the project 10 years ago. So I guess if "accounting for 18 | [1/3rd of app submissions to AppStore](https://medium.com/flutter/flutter-in-production-f9418261d8e1) 19 | or Play” is what "dying" looks like, I’m here for it. 🙂 20 | 21 | Today, Google's Dart team announced they are 22 | [stopping their work on "macros" ](https://medium.com/dartlang/an-update-on-dart-macros-data-serialization-06d3037d4f12). 23 | Macros was planned as a new language feature to make it easier for Flutter and 24 | Dart developers to express ideas requiring repetitive code (for example data 25 | serialization) from simple syntax. C++, Rust, etc. all have variants of a 26 | [macros]() feature with 27 | various different tradeoffs. Dart took a particularly ambitious flavor that 28 | ultimately proved unwieldy to implement to the Google team's satisfaction. 29 | 30 | Two reasons Google took this step: 31 | 32 | 1. They’ve realized they can’t make macros pass their performance goals (without 33 | other even larger changes to the ecosystem or language). 34 | 2. The years of prototyping macros (with its ambitious scope), hasn’t been worth 35 | the effort/reward tradeoff. 36 | 37 | Google is now breaking macros into smaller features and shipping those, and then 38 | throwing out the parts of macros that they couldn’t make perform well enough to 39 | ship. 40 | 41 | Not the outcome the Dart community was rooting for, but overall I’m glad. 42 | 43 | I'm always glad to see focus. 44 | 45 | I was an intern at Apple 20 years ago. When I was there, Steve Jobs came and 46 | spoke to all the interns. His talk was simple. He said “The challenge in life is 47 | saying ‘no’. You have to say ‘no’ to make room for the ‘yes’. There will always 48 | be more ‘yes’.” 49 | 50 | That has stuck with me a long time and informed my choices for how I build 51 | products and do business. It’s part of why Shorebird so far only has one 52 | product, and why Flutter stuck to ‘just mobile’ for so long. Shorebird will 53 | build many more things, but we’re choosing to focus on instant updates for now. 54 | 55 | The macros work started while I still led the Dart team over 2 years ago. This 56 | long development cycle (and public discussion thereof) has allowed macros grow 57 | in the public consciousness to be seen as Dart’s coming magic bullet, here to 58 | solve all our problems at once. It never was, and never could be. 59 | 60 | Obviously, I wish the team had reached a go/no-go earlier, but I’m glad they 61 | have now. Hopefully now we get a bunch of interesting smaller things this year 62 | as a result. We’ll see. 63 | 64 | The Google Dart team and wider community are full of passionate and talented 65 | people. I’m looking forward to see what amazing things we do next. 66 | 67 | Onward. 68 | -------------------------------------------------------------------------------- /src/content/blog/desktop-in-production.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Production Desktop Support 3 | author: bryanoltman 4 | description: Announcing that desktop platforms are now production-ready 5 | date: 2025-02-07 6 | cover: stable-desktop-cover.png 7 | --- 8 | 9 | We’re excited to announce that, as of today, our desktop (Windows, Linux, and 10 | macOS) support is moving out of beta. Shorebird now goes everywhere Flutter 11 | goes. 12 | 13 | If you’re familiar with Shorebird, creating releases and patches for these new 14 | platforms will look very familiar: 15 | 16 | ```sh 17 | shorebird release linux 18 | shorebird release macos 19 | shorebird release windows 20 | ``` 21 | 22 | ```sh 23 | shorebird patch linux 24 | shorebird patch macos 25 | shorebird patch windows 26 | ``` 27 | 28 | The patching mechanism for each of these platforms does not use a simulator, so 29 | there is no performance penalty when running patched code. 30 | 31 | If you’re using Flutter on desktop, we’d love to hear from you! Let us know if 32 | you run into any issues or have ideas for new features by creating a 33 | [new GitHub issue](https://github.com/shorebirdtech/shorebird/issues/new?template=Blank+issue). 34 | You can also reach us on [Discord](https://discord.gg/shorebird). 35 | -------------------------------------------------------------------------------- /src/content/blog/development-workflow.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: How to integrate Shorebird into your development workflow 3 | author: felangel 4 | description: Announcing our opinionated development workflow guide. 5 | date: 2024-09-25 6 | cover: development-workflow-cover.png 7 | --- 8 | 9 | Our customers have been asking for an opinionated development workflow which 10 | integrates Shorebird so that they can spend more time shipping and less time 11 | defining and building a release/patch pipeline that integrates Shorebird. 12 | 13 | We're excited to announce that we've put together a 14 | [development workflow guide](https://docs.shorebird.dev/guides/development-workflow) 15 | which includes: 16 | 17 | - 🪵 Branching and tagging strategy 18 | - ✅ Automated continuous integration checks 19 | - 🚀 Automated releases for iOS and Android 20 | - 🧩 Automated patches for iOS and Android 21 | - 👀 Staged patches that are ready to promote to production with 1 click 22 | - 🐙 Ready to use GitHub Workflows 23 | - 💙 An open source example application for reference 24 | 25 | If you have any questions or feedback, reach out to us on 26 | [Discord](https://discord.gg/shorebird) -- we'd love to help! 27 | -------------------------------------------------------------------------------- /src/content/blog/flutterconusa-2025-sponsor.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Shorebird Sponsors Fluttercon USA 2025 3 | author: shorebirdtech 4 | description: 5 | Join us June 25–26 to connect with the Flutter community in North America. 6 | date: 2025-05-06 7 | cover: flutterconusa-2025-cover.png 8 | --- 9 | 10 | It’s been a year full of in person conferences and meetups for us and we are 11 | just getting started. It’s amazing to be able to get out into the community and 12 | see how Shorebird is being used but also hearing feedback from current and 13 | prospective customers. It seems like once developers realize the tools that 14 | Shorebird adds to their Flutter toolbox they can’t help but want to get it 15 | integrated into their current project. 16 | 17 | So with that knowledge we’re setting sights on the largest Flutter conference in 18 | North America. Shorebird is proud to sponsor 19 | [Fluttercon USA 2025](https://www.flutterconusa.dev) taking place June 25–26 in 20 | New York City! 21 | 22 | As strong supporters of the Flutter community, we’re thrilled to join hundreds 23 | of developers, teams, and product leaders to talk about building, scaling, and 24 | shipping faster with Flutter. At Fluttercon USA you will be able to learn from 25 | industry experts, attend diverse sessions, engage with a vibrant community of 26 | developers, and more. It’s also co-located with Droidcon NYC so you can expand 27 | your learning and networking horizons. And new this year, 28 | [the techlead summit](https://www.techlead-summit.com). This track is designed 29 | for Principal Engineers, Senior Developers & Managers to be able to talk about 30 | scaling teams, fostering culture and how to drive impact from the team 31 | management side of things. 32 | 33 | ![Fluttercon USA 2025 Register Now Banner](../../assets/blog/flutterconusa-2025-sponsor/register-now-banner.jpg) 34 | 35 | If you were already looking at attending Fluttercon but haven't pulled the 36 | trigger just yet we have something for you. 37 | 38 | **Use promo code SHOREBIRD15 for 15% off your conference registration!** 39 | Register now at [https://www.flutterconusa.dev](https://www.flutterconusa.dev). 40 | But be sure to act fast, the coupon code is valid now through the end of May. 41 | 42 | We’ll be there to share how Shorebird helps you 43 | 44 | - Ship Flutter app updates instantly with no app store review delay 45 | - Deploy fixes and features daily with confidence 46 | - Scale mobile CI/CD workflows 47 | 48 | Stop by to say hi, learn something new, and grab some Shorebird swag. 49 | 50 | See you in NYC 🏙! 51 | -------------------------------------------------------------------------------- /src/content/blog/improved-patch-delivery.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Improved Patch Delivery 3 | author: felangel 4 | description: 5 | Announcing improved global patch delivery, availability, and performance. 6 | date: 2024-09-05 7 | cover: improved-patch-delivery-cover.png 8 | --- 9 | 10 | We're excited to announce some improvements to cloud infrastructure which 11 | improve patch delivery, availability, and performance around the world 🥳 12 | 13 | ## What's Changed 14 | 15 | When a patch is published via `shorebird patch`, the generated patch artifact is 16 | uploaded to Shorebird's cloud. On app launch, the corresponding release running 17 | on users' devices will ping Shorebird's API to check whether a newer patch is 18 | available. If a newer patch is available, Shorebird's API will respond with a 19 | link to the patch artifact and the patch is then downloaded and installed on the 20 | device. 21 | 22 | We've made some improvements to how we store and serve patch artifacts to both 23 | improve availability and performance — patches can be downloaded faster in more 24 | places around the world. 25 | 26 | ## Wider Availability 27 | 28 | We've made some changes to our cloud infrastructure to enable Shorebird to 29 | deliver patches to more regions around the world. You may now find that users 30 | are able to download patches in regions that were previously unavailable. 31 | 32 | ![China Patch availability image](../../assets/blog/improved-patch-delivery/china-availability.png) 33 | 34 | ## Faster Downloads 35 | 36 | Our cloud infrastructure improvements have also reduced the time it takes to 37 | download patches around the world. The following snapshot of data illustrates 38 | the average time it took to download a 1mb patch before and after the 39 | improvements. 40 | 41 | **Average Response Times** 42 | 43 | | Location | Before | After | 44 | | -------------- | :----: | :---: | 45 | | Netherlands | 543ms | 59ms | 46 | | USA | 556ms | 137ms | 47 | | Germany | 754ms | 211ms | 48 | | India | 1730ms | 156ms | 49 | | United Kingdom | 748ms | 78ms | 50 | | Australia | 1113ms | 153ms | 51 | | Nigeria | 1891ms | 826ms | 52 | | Korea | 1949ms | 45ms | 53 | 54 | _Note: snapshot of data taken on 9/5/2024_ 55 | 56 | ## Get Started 57 | 58 | These infrastructure improvements are already rolled out to all Shorebird 59 | customers around the world. 🥳 60 | 61 | If you're new to Shorebird and want to get started, head over to the 62 | [Shorebird Console](https://console.shorebird.dev). 63 | -------------------------------------------------------------------------------- /src/content/blog/ios-beta.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: iOS Beta 3 | author: shorebirdtech 4 | description: Shorebird Code Push for iOS beta announcement 5 | date: 2024-02-01 6 | cover: ios-beta-cover.png 7 | --- 8 | 9 | Shorebird Code Push allows you to update your Flutter app instantly over the air 10 | and deploy fixes directly to end users' devices. 11 | 12 | Shorebird's Android support has been production ready for nearly a year and is 13 | used by thousands of apps. Hundreds of early adopters have tried our iOS support 14 | during alpha these last 7 months. 15 | 16 | We're excited to announce that Code Push for Flutter is now in beta for iOS! 17 | 18 | iOS beta requires the latest version of Shorebird CLI (`0.25.0`) and the latest 19 | stable version of Flutter (`3.16.9`). 20 | 21 | ## 🚀 Get Started 22 | 23 | Get started now with our 24 | [Quick Start Guide](https://docs.shorebird.dev/guides/code_push_quickstart) and 25 | join the Shorebird community on [Discord](https://discord.gg/shorebird)! 26 | 27 | ## 🚦 Status 28 | 29 | Code Push for iOS is now beta and safe for production apps. If you've been 30 | waiting to try Shorebird until there was stable iOS support, now is the time! 31 | 32 | If you encounter any problems, 33 | [please file an issue](https://github.com/shorebirdtech/shorebird/issues/new/choose) 34 | or reach out over [Discord](https://discord.gg/shorebird) we will work with you 35 | to address it immediately! 36 | 37 | ## 🔥 iOS improvements from alpha 38 | 39 | - 🚀 Apps run 100x faster before patching. 40 | - 🏎️ Apps run 2x faster after patching. 41 | - 📦 Patch sizes are 10x smaller 42 | - 🔨 Hundreds of other issues resolved. 43 | 44 | Thank you again to the thousands of developers who have supported Shorebird and 45 | provided feedback thus far. 46 | 47 | ## 🚏 Road to 1.0 48 | 49 | This release is marked "beta" rather than 1.0 due to a couple outstanding 50 | issues: 51 | 52 | - `--obfuscate` is not currently supported on iOS 53 | ([#1619](https://github.com/shorebirdtech/shorebird/issues/1619)). 54 | - Apps run slower after patching on iOS (unpatched apps run at full speed) 55 | ([#674](https://github.com/shorebirdtech/shorebird/issues/674)) 56 | 57 | Both of these will be addressed in the coming weeks. There is no change to app 58 | speed before patches have been applied. Android builds run at full speed both 59 | patched and unpatched. 60 | 61 | ## 🐦 Try Shorebird 62 | 63 | Please 64 | [try adding Shorebird to your app](https://docs.shorebird.dev/guides/code_push_quickstart) 65 | on iOS and let us know what you think! 66 | 67 | See you on [Discord](https://discord.gg/shorebird) 👋 68 | 69 | Thanks, 70 | 71 | The Shorebird Team (Eric, Bryan, and Felix) 72 | -------------------------------------------------------------------------------- /src/content/blog/macos-beta.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: macOS Desktop Support (beta) 3 | author: bryanoltman 4 | description: Announcing the beta release of macOS desktop support 5 | date: 2024-12-16 6 | cover: macos-beta-cover.png 7 | --- 8 | 9 | Shorebird now supports updating Flutter apps built for Mac desktop. 10 | 11 | This support is in beta and only supports Arm (Apple Silicon) macs at this time. 12 | We intend to support Intel macs in the future, but that may still be several 13 | weeks away. We're beginning Windows desktop support next and you can follow our 14 | progress [on GitHub](https://github.com/shorebirdtech/shorebird/issues/397). 15 | 16 | The release and patch flow is the same as you’re used to with iOS and Android: 17 | 18 | ```sh 19 | # Creates a new macOS release 20 | shorebird release macos 21 | ``` 22 | 23 | ```sh 24 | # Patches a macOS release 25 | shorebird patch macos --release-version=1.2.3+4 26 | ``` 27 | 28 | As always, we want your feedback! We'd love for you to try this out and let us 29 | know what you think. Let us know if you run into any issues or have ideas for 30 | new features by 31 | [creating a new GitHub issue](https://github.com/shorebirdtech/shorebird/issues/new/choose) 32 | -------------------------------------------------------------------------------- /src/content/blog/organizations.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Using Shorebird with your Team 3 | author: shorebirdtech 4 | description: 5 | Announcing "Organizations" support for improved collaboration within teams 6 | date: 2024-10-10 7 | cover: organizations-cover.png 8 | --- 9 | 10 | _Shorebird Code Push allows developers to deploy fixes to Flutter apps 11 | instantly, over the air, to end users’ devices. It takes less than 5 minutes to 12 | integrate and requires no changes to your code or dev workflows. Updating 13 | through Shorebird can change any amount of Dart code in your app and is designed 14 | to help you fix your app quickly and safely, while still complying with Apple 15 | and Google store policies._ 16 | 17 | Shorebird Pro subscribers have long enjoyed per-app collaboration, where they 18 | were able to share a single app with multiple other developers. However until 19 | today it was not possible to share groups of apps to groups of people all at 20 | once. Nor was it possible to set up sharing without having apps in the first 21 | place. To address both of these, we've introduced "Organizations" support in 22 | Shorebird. 23 | 24 | Your team can now collaborate on a group of apps together, and control access to 25 | that group of apps in a single place. It's also now possible to have the person 26 | who sets up billing and access for an organization be separate from the person 27 | who creates the apps. 28 | 29 | See our docs for more information: https://docs.shorebird.dev/orgs/ 30 | -------------------------------------------------------------------------------- /src/content/blog/patch-rollback.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Patch Rollbacks 3 | author: shorebirdtech 4 | description: Announcing support for rolling back patches. 5 | date: 2024-08-09 6 | cover: patch-rollback-cover.png 7 | --- 8 | 9 | _Shorebird Code Push allows developers to deploy fixes to Flutter apps 10 | instantly, over the air, to end users’ devices. It takes less than 5 minutes to 11 | integrate and requires no changes to your code or dev workflows. Updating 12 | through Shorebird can change any amount of Dart code in your app and is designed 13 | to help you fix your app quickly and safely, while still complying with Apple 14 | and Google store policies._ 15 | 16 | Shorebird already has many systems in place to make sure your patches are always 17 | improving your app for users. This includes providing you with 18 | [staging](https://docs.shorebird.dev/guides/staging-patches/) and testing 19 | facilities for your own QA, 20 | [on-device automatic-rollback](https://docs.shorebird.dev/architecture/) if a 21 | patch fails to load, and patch-install failure reporting. Until now, it has been 22 | possible to disable new installs of patches, or send new patches to users. 23 | Today, it’s now possible to issue global roll-backs of patches to all users. 24 | 25 | Patches made with Shorebird Flutter 3.22.3 or later support global rollback. 26 | Rollbacks can be initiated from the 27 | [Shorebird Console](https://console.shorebird.dev/). See our 28 | [rollback docs](https://docs.shorebird.dev/code-push/rollback/) for more info. 29 | 30 | There is no charge for the use of the rollback service, since a rollback is a 31 | patch removal rather than install. When rolling back from one patch to another, 32 | if devices do not still contain the older patch, downloads and installs of that 33 | older patch will count against monthly patch installs. 34 | 35 | As always, we’re available every day on Discord and happy to answer any 36 | questions you may have. 37 | 38 | See you on [Discord](https://discord.gg/shorebird) 👋 39 | 40 | Thanks, 41 | 42 | The Shorebird Team (Eric, Bryan, and Felix) 43 | -------------------------------------------------------------------------------- /src/content/blog/patch-signing-beta.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Patch Signing Beta 3 | author: bryanoltman 4 | description: Announcing Patch Signing for Shorebird Code Push. 5 | date: 2024-06-05 6 | cover: patch-signing-cover.png 7 | --- 8 | 9 | Shorebird’s code push allows developers to update their Flutter apps instantly, 10 | over the air, deploying fixes directly to end users’ devices. Our solution takes 11 | less than 5 minutes to integrate and requires no code changes. Shorebird’s code 12 | push can update any Dart code in your app and we’ve designed the system to 13 | comply with Apple and Google store policies without sacrificing performance 14 | (even after patching). 15 | 16 | One of our goals is that Shorebird should be the default for all Flutter users. 17 | To do that, using Shorebird needs to be a strict upgrade from default Flutter. 18 | This includes ensuring that Shorebird is always helping with the security and 19 | privacy of your application. 20 | 21 | Today we're announcing another layer of security for Shorebird: patch signing. 22 | Patch signing allows you to cryptographically sign updates to your app and make 23 | your app require that patch contents are verified (via cryptographic signature) 24 | before applying the patch. 25 | 26 | This uses the same signing technologies that are used when distributing your app 27 | through the app stores. With patch signing, your app has the ability to 28 | independently verify patch contents without trusting any system or networks 29 | (including Shorebird) that might have been involved in transporting the patch 30 | from you to your users. 31 | 32 | Patch signing is an optional addition to the many ways in which Shorebird 33 | already works to protect the security of all our customers. We always take many 34 | precautions to protect the security of your app, including limiting what data 35 | leaves your servers (we never see or store your source code), securing what data 36 | we do store both via encryption in transit and in rest, cryptographically 37 | hashing and validating the contents of any patch you create, as examples. You 38 | can see a full breakdown of security practices we follow on your behalf in our 39 | [public security policies](https://handbook.shorebird.dev/security). 40 | 41 | The patch signing we’ve shipped today is marked as “beta”. The feature is fully 42 | functional, but we expect there to be rough edges in how the patch signing 43 | integrates with your existing developer flows. A system is only as secure as its 44 | weakest link, so improving our integrations with your preferred key management 45 | systems, etc. is where we go next and where we need your help. 46 | 47 | We’re looking for companies to work with us in testing and improving patch 48 | signing over the next few weeks. If you are interested, please give it a try: 49 | https://docs.shorebird.dev/guides/patch-signing/ You can also reach out to us 50 | via [GitHub](https://github.com/shorebirdtech/shorebird/), 51 | [Discord](https://discord.gg/shorebird) or [email](contact@shorebird.dev) should 52 | you have feedback or questions. 53 | 54 | We’d love to help you integrate Shorebird code push into your application. 55 | Please [reach out](mail:contact@shorebird.dev) to us if you have any questions 56 | or need help getting started. 57 | 58 | If you're curious about what we had to change in Dart to make this all possible, 59 | check out our [previous post](how-we-built-code-push). 60 | -------------------------------------------------------------------------------- /src/content/blog/shorebird-codemagic.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Shorebird & Codemagic Integration 3 | author: felangel 4 | description: Announcing Shorebird Integration in Codemagic 5 | date: 2025-02-04 6 | cover: codemagic-cover.png 7 | --- 8 | 9 | We're very excited to announce that we've been working with the folks at 10 | [Codemagic](https://codemagic.io) and Shorebird's Code Push solution is now 11 | directly integrated into Codemagic's CI/CD 🥳 12 | 13 | You can configure release and patch workflows directly within Codemagic's UI 14 | allowing you to integrate Code Push into your Flutter app with just a few clicks 15 | ✨ 16 | 17 | Watch our full walkthrough below ↓ 18 | 19 |
20 | 21 |
22 | -------------------------------------------------------------------------------- /src/content/blog/simplified-pricing.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Simplified, Flexible Pricing 3 | author: shorebirdtech 4 | description: Announcing simplified pricing for Shorebird 5 | date: 2024-08-27 6 | cover: simplified-pricing-cover.png 7 | --- 8 | 9 | Today we’re announcing simplified pricing for Shorebird. We offer two plans: 10 | **Free** and a new **Pro** plan. 11 | 12 | ### Free 13 | 14 | - Up to 5,000 patch installs per month 15 | - Unlimited Apps 16 | - 1 User 17 | 18 | ### Pro 19 | 20 | - $20 per month 21 | - Includes 50,000 patch installs per month 22 | - Additional installs at $0.0004 per install, with configurable spending limit 23 | - Unlimited Apps 24 | - Unlimited Collaborators 25 | 26 | Previously, Shorebird offered a variety of usage tiers. Customers told us this 27 | was confusing and harder to manage for apps with variable updating needs. So 28 | we’ve moved to a single, simpler paid plan to answer this need. 29 | 30 | With Pro, your only commitment is to the $20 monthly platform fee, which 31 | includes 50,000 patches delivered. Use as much or as little beyond that as you 32 | want, and only get billed for what you use. 33 | 34 | ![Pro Plan](../../assets/blog/simplified-pricing/ProPlan.png) 35 | 36 | Customers can control their spending limit from the 37 | [Shorebird Console](https://console.shorebird.dev). Your spending limit defaults 38 | to $0 and we will automatically notify you via email once when you’re close to 39 | your limit and again when you’ve reached your limit. 40 | 41 | ![Usage Limit](../../assets/blog/simplified-pricing/UsageLimit.png) 42 | 43 | Existing Shorebird customers with “Hobby” or “Teams” will see no changes. You 44 | can keep your plan as it exists today, or you’re welcome to transition to this 45 | new usage-based billing at any time on the 46 | [Shorebird Console](https://console.shorebird.dev). 47 | 48 | We made a bunch of improvements behind the scenes to make this happen. If you 49 | have any questions about billing, or would like to purchase Shorebird in a 50 | different way, please don’t hesitate to reach out at contact@shorebird.dev. 51 | -------------------------------------------------------------------------------- /src/content/blog/tom-joins-shorebird.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Building The Flock - Tom Arra joins Shorebird! 3 | author: tomarra 4 | description: Starting the growth outside of just Engineering 5 | date: 2025-02-10 6 | cover: tom-joins-shorebird-cover.png 7 | --- 8 | 9 | I’m excited to share that I’ve joined Shorebird! 10 | 11 | For me, this decision wasn’t just about the next step in my career. It was about 12 | doubling down on Flutter and multi-platform development. 13 | 14 | ## A Longstanding Passion for Flutter 15 | 16 | I’ve been involved in the Flutter community since 2019, starting during my time 17 | at BMW and later at Very Good Ventures. Over the years, I’ve seen Flutter grow 18 | from an ambitious new framework to a powerhouse for multi-platform development. 19 | I’ve worked with teams around the world pushing Flutter to its limits, helping 20 | scale production apps, and advocating for its potential to simplify and 21 | accelerate development across mobile, web, and desktop. 22 | 23 | Through it all, my belief has only strengthened: multi-platform should be the 24 | standard for application development. Businesses and developers shouldn’t have 25 | to choose between performance, maintainability, and reach. Flutter has already 26 | proven that a single codebase can deliver beautiful, native experiences across 27 | platforms, and Shorebird is building the tools to push that even further. 28 | 29 | ## Why Shorebird? 30 | 31 | Right now, Shorebird is tackling one of the biggest pain points in mobile 32 | development—getting updates to users faster. With code push, developers can fix 33 | bugs and ship improvements instantly, without waiting for app store approvals. 34 | This alone is a game-changer, but it’s just the beginning of what Shorebird is 35 | building. 36 | 37 | When the opportunity came to join a team focused on solving real-world developer 38 | challenges in the Flutter ecosystem, I knew I had to be part of it. 39 | 40 | ## Staying in the Flutter Ecosystem 41 | 42 | The Flutter community has been an incredible place to be, and I wanted to stay 43 | in this space because I truly believe in its potential. Multi-platform 44 | development isn’t just a nice-to-have—it’s the best way to build apps. I’ve seen 45 | firsthand how Flutter enables teams to move faster, deliver high-quality 46 | experiences, and reach more users with less overhead. 47 | 48 | At Shorebird, I’ll focus on helping the company grow beyond engineering, 49 | encompassing product, sales, marketing, and operations, to provide these tools 50 | to as many Flutter developers as possible. The Shorebird team already includes 51 | some of the best minds in Flutter, and I’m excited to contribute to their 52 | vision. 53 | 54 | ## What’s Next? 55 | 56 | If you’re a Flutter developer, I’d love to connect and hear your thoughts on 57 | what you need to ship better apps, faster. Shorebird is just getting started, 58 | and there’s a lot of exciting work ahead. 59 | 60 | Let’s build the future of multi-platform development—together. 61 | -------------------------------------------------------------------------------- /src/content/blog/tracks-percentage-rollouts-a-b-testing.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Tracks, Percentage Rollouts and A/B testing 3 | author: eseidel 4 | description: Announcing Tracks, Percentage Rollouts and A/B testing 5 | date: 2024-11-14 6 | cover: tracks-cover.png 7 | --- 8 | 9 | Building on the success of our brand-new 10 | [`shorebird_code_push` package](https://pub.dev/packages/shorebird_code_push/versions/2.0.0) 11 | 2.0, we're announcing patch tracks, which can be used to support 12 | percentage-based rollouts and A/B testing within Shorebird. 13 | 14 | The `shorebird_code_push` package is a completely optional package that allows 15 | developers to customize the user experience of downloading and installing 16 | over-the-air updates with Shorebird. It was built for teams that want more 17 | control over when updates are downloaded and which users receive those updates. 18 | 19 | Shorebird strongly believes in user privacy, and we never collect any 20 | information from our customer's customers. This means that we can't tell one of 21 | your customers apart from another. This has previously prevented us from being 22 | able to offer patch rollout options that target specific users. 23 | 24 | However, with the updated package:shorebird_code_push, we've provided the API 25 | tools to make it easy for you to provide your own group-based control over who 26 | gets what updates when. With patch tracks, you can support QA testing, a public 27 | beta, or even for controlled percentage-based rollout across your userbase. 28 | 29 | `ShorebirdUpdater` methods `checkForUpdate` and `update` now take an optional 30 | `track` parameter which affords you powerful control over app updates in the 31 | field. 32 | 33 | Examples of features it is now possible for you to add to your process: 34 | 35 | ### Group based update distribution 36 | 37 | The `shorebird` command line now takes a `--track` parameter which allows you to 38 | specify the track to send a patch to. For example, you can use 39 | `shorebird patch ios --track staging` to submit a patch to your iOS builds which 40 | is only available when requesting updates to the `staging` track. 41 | 42 | This can be used for example to distribute updates only to your QA team for 43 | testing, which you can then later promote to the `stable` track for distribution 44 | to all users. 45 | 46 | ### Percentage Rollouts 47 | 48 | Similar to groups, it is now possible to implement percentage rollouts of 49 | patches with Shorebird. Currently we do not provide UI for controlling rollouts, 50 | but rather the tools to allow customers to do so on their own. We've written a 51 | guide demonstrating how this can be accomplished: 52 | https://docs.shorebird.dev/guides/percentage-based-rollouts/ 53 | 54 | ### A/B Testing 55 | 56 | These same track APIs are also able to support A/B testing. 57 | 58 | The logic is very similar to a percentage based rollout above, just determining 59 | whether to use patch A or B based on some other criteria. 60 | 61 | ## Get Started 62 | 63 | You can try out the new version now by adjusting your `pubspec.yaml` to use 64 | version 2.0 of `shorebird_code_push` and re-releasing a new version of your 65 | application using the revision of Flutter 3.24.5. 66 | 67 | ```yaml 68 | dependencies: 69 | shorebird_code_push: ^2.0.0 70 | ``` 71 | 72 | We'd love to hear your feedback! If there's anything you'd like to see adjusted 73 | or improved, please 74 | [let us know by filing an issue](https://github.com/shorebirdtech/updater/issues/new). 75 | -------------------------------------------------------------------------------- /src/content/blog/viewing-logs.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Viewing logs in released apps 3 | author: bryanoltman 4 | description: How to view logs for an app without a debugger attached. 5 | date: 2024-08-20 6 | cover: viewing-logs-cover.png 7 | --- 8 | 9 | Whether you're using a logging framework or the humble `print` function, logs 10 | provide a window into how your app is working (or not working) in real-time. 11 | Being able to view logs can help you more quickly locate and fix errors than you 12 | would be able to by only observing your app's behavior. 13 | 14 | Developers most often see log output while coding an app, but did you know you 15 | can also see logs for release apps without needing to attach a debugger? 16 | 17 | ## `logcat` for Android 18 | 19 | All Android system output can be viewed using the 20 | [`logcat`](https://developer.android.com/tools/logcat) command line tool. You 21 | can try this out by connecting your Android device via USB and running 22 | `adb logcat` in your terminal. 23 | 24 | Note: adb will need to be on your path for this to work. If you see an error 25 | like `command not found: adb` or 26 | `'adb' is not recognized as an internal or external command`, you will need to 27 | add `adb` to your PATH. StackOverflow has good answers to help with this for 28 | [macOS/Linux](https://stackoverflow.com/questions/10303639/adb-command-not-found) 29 | and 30 | [Windows](https://stackoverflow.com/questions/20564514/adb-is-not-recognized-as-an-internal-or-external-command-operable-program-or) 31 | 32 | Without any filtering, `adb logcat` is _very_ noisy. To show just the output for 33 | your Flutter app, you can filter the output using `adb logcat | grep flutter` on 34 | macOS/Linux or `adb logcat | findstr flutter` on Windows. 35 | 36 | ![](../../assets/blog/release-logs/TerminalLogcat.png) 37 | 38 | ## Console.app for iOS 39 | 40 | macOS includes a utility app named 41 | [Console](https://support.apple.com/guide/console/welcome/mac) that shows all 42 | system logs. 43 | 44 | To open the Console app, type + Space, type 'Console', 45 | and press Enter. 46 | 47 | By default, this shows logs for your Mac, but it can also be used to view logs 48 | for your iPhone, iPad, Apple Watch, etc. 49 | 50 | To see system logs, connect your device to your Mac via USB, select it in the 51 | left column, and press the "Start" button in the top toolbar. 52 | 53 | ![](../../assets/blog/release-logs/EmptyConsoleStartButtonArrow.png) 54 | 55 | Without filtering, these logs are _very_ noisy. To filter out logs that are not 56 | from your app, type your app's name in the search bar and press enter (for 57 | Flutter apps, this defaults to "Runner"). You can then right-click on "Runner" 58 | in the Process column and select "Show Process 'Runner'" 59 | 60 | ![](../../assets/blog/release-logs/ConsoleShowProcessMenu.png) 61 | 62 | With this filter applied, we are only shown logs that apply to our app. 63 | 64 | ![](../../assets/blog/release-logs/ConsolePatchCheckResponse.png) 65 | -------------------------------------------------------------------------------- /src/content/blog/windows-beta.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Windows Desktop Support (beta) 3 | author: eseidel 4 | description: Announcing the beta release of Windows desktop support 5 | date: 2025-01-09 6 | cover: windows-beta-cover.png 7 | --- 8 | 9 | Shorebird now supports updating Flutter apps built for Windows desktop! 🥳 10 | 11 | ![screenshot](../../assets/blog/windows-desktop/screenshot.png) 12 | 13 | The release and patch flow is the same as iOS, Android and Mac: 14 | 15 | ```sh 16 | # Creates a new windows release 17 | shorebird release windows 18 | ``` 19 | 20 | ```sh 21 | # Patches a windows release 22 | shorebird patch windows --release-version=1.2.3+4 23 | ``` 24 | 25 | Windows support is in beta and only supports Windows x64 at this time. Let us 26 | know if you require Windows arm64 support. 27 | 28 | Try this out and let us know what you think. Let us know if you run into any 29 | issues or have ideas for new features by 30 | [creating a new GitHub issue](https://github.com/shorebirdtech/shorebird/issues/new/choose) 31 | -------------------------------------------------------------------------------- /src/content/blog/workshops.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Online Shorebird Workshops 3 | author: felangel 4 | description: Announcing online workshops to help you get started with Shorebird. 5 | date: 2025-01-06 6 | cover: workshops-cover.png 7 | --- 8 | 9 | We're excited to announce the team at Shorebird will be hosting free 1 hour long 10 | online workshops for getting started with Shorebird. 11 | 12 | You can register now at https://shorebird.dev/workshops 13 | 14 | Our first workshops of the year will be on: 15 | 16 | - **Monday January 13th at 7:30pm CST** 17 | - **Wednesday February 5th at 7:30pm CST** 18 | - **Wednesday February 19th at 8:00am CST** 19 | 20 | We hope to have more dates in the future based on interest from the community. 21 | 22 | In order to provide a high quality experience, we've limited the number of 23 | available spots so be sure to sign up as soon as possible to ensure a spot. 24 | 25 | In these workshops we’ll walk through all the steps needed to get Shorebird 26 | working on a Flutter app of your choice. Either follow along with a provided 27 | Flutter app or bring your own app. 28 | 29 | Along the way we’ll look at how to manage apps, releases, patches, and more 30 | using the Shorebird CLI and Console. We will also cover how to use 31 | `package:shorebird_code_push` to customize the user experience. 32 | 33 | By the end of the workshop, you should have Shorebird’s code push solution 34 | integrated into a Flutter app and have a solid understanding of how to deliver 35 | over the air updates to your users. 36 | 37 | We look forward to seeing you there 👋 38 | -------------------------------------------------------------------------------- /src/content/blog/yearly-plans.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Introducing Yearly Plans 3 | author: shorebirdtech 4 | description: 5 | We’re excited to roll out Yearly Plans for Shorebird designed to give you more 6 | flexibility and predictability as you build and scale your apps. 7 | date: 2025-04-23 8 | cover: 'yearly-plans-cover.png' 9 | --- 10 | 11 | We’re excited to roll out Yearly Plans for Shorebird. These plans are designed 12 | to give you more flexibility and predictability as you build and scale your 13 | apps. 14 | 15 | ## Why Yearly Plans? 16 | 17 | As our customer base has grown, so has the demand for yearly plans. Based on 18 | your feedback, the need typically comes down to two main reasons: 19 | 20 | 1. **Purchasing Process** - We’ve heard from many of you that yearly plans are 21 | essential to your internal purchasing processes—whether you’re part of a 22 | large organization with budget cycles or a small team looking to simplify 23 | payments. Some teams need yearly invoicing for budgeting, while others just 24 | want the convenience of avoiding monthly billing fluctuations. 25 | 2. **Unable to Predict Monthly Volume** - When starting with a new service, it’s 26 | tough to know how your team will use it until you dive in and experiment. 27 | We’ve seen usage spikes when business-critical issues arise are the moments 28 | when fast patches matter most but weren’t accounted for in the monthly 29 | budget. Whether you’re launching a new feature, onboarding users, or running 30 | a seasonal campaign, monthly patch usage can vary wildly. Picking the “right” 31 | monthly plan can become a headache. 32 | 33 | With our new yearly option, these issues are a thing of the past. 34 | 35 | ## How It Works 36 | 37 | - **One payment. 12 months of Shorebird.** Pay once upfront and get a full year 38 | of access to Shorebird. No more chasing monthly invoices or wrangling with 39 | payment systems. 40 | - **Patches credited upfront.** You’ll receive your entire year’s worth of 41 | patches on day one. Use them when you need them—whether you’re shipping daily 42 | or ramping up after a big launch. You can go beyond our typical monthly 43 | limits, as long as you stay within your new annual total. That means freedom 44 | to move fast when it matters most. 45 | - **No overages, no surprises** With our yearly plans, what you pay upfront is 46 | it. No surprise charges. This means you can scale your patch usage during busy 47 | times and slow down during quieter periods all without worrying about trigging 48 | unexpected fees. 49 | 50 | ## Who’s This For? 51 | 52 | Anyone can sign up for Yearly Plans as its available starting today via our 53 | Shorebird Console. Not sure if it’s right for you? Here are some use cases that 54 | inspired this update: 55 | 56 | - Teams who want predictable billing 57 | - Companies with seasonal usage patterns 58 | - Anyone who wants to prepay for peace of mind 59 | 60 | ## How to Switch 61 | 62 | You can upgrade to an annual plan right from the 63 | [Shorebird Console](https://console.shorebird.dev), or reach out to us via our 64 | [Discord Server](https://discord.gg/shorebird) if you have questions or want to 65 | talk through your options. 66 | -------------------------------------------------------------------------------- /src/content/config.ts: -------------------------------------------------------------------------------- 1 | import { glob } from 'astro/loaders'; 2 | import { defineCollection, z } from 'astro:content'; 3 | 4 | const convertDateToUTC = (date: Date) => 5 | new Date( 6 | date.getUTCFullYear(), 7 | date.getUTCMonth(), 8 | date.getUTCDate(), 9 | date.getUTCHours(), 10 | date.getUTCMinutes(), 11 | date.getUTCSeconds(), 12 | date.getUTCMilliseconds(), 13 | ); 14 | 15 | const blogCollection = defineCollection({ 16 | loader: glob({ pattern: '**/*.md', base: './src/content/blog' }), 17 | schema: z.object({ 18 | title: z.string(), 19 | description: z.string(), 20 | author: z.string(), 21 | date: z.date().transform(convertDateToUTC), 22 | cover: z.string(), 23 | }), 24 | }); 25 | 26 | const successStoriesCollection = defineCollection({ 27 | loader: glob({ pattern: '**/*.md', base: './src/content/success-stories' }), 28 | schema: z.object({ 29 | title: z.string(), 30 | description: z.string(), 31 | cover: z.string(), 32 | date: z.date().transform(convertDateToUTC), 33 | highlights: z.array(z.string()), 34 | }), 35 | }); 36 | 37 | export const collections = { 38 | blog: blogCollection, 39 | successStories: successStoriesCollection, 40 | }; 41 | -------------------------------------------------------------------------------- /src/content/success-stories/easyspend.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: EasySpend 3 | description: 4 | Next generation fintech companies turn to cloud services like Shorebird to 5 | help them easily deploy and stay up to date across all of their platforms. 6 | date: 2025-03-07 7 | cover: easyspend-cover.png 8 | highlights: ['Over 1,000 monthly active users'] 9 | --- 10 | 11 | 12 | 13 | EasySpend is a next-generation fintech company based in Lagos, Nigeria, with a 14 | mission to transform financial transactions for individuals and businesses. 15 | Offering a suite of services including virtual cards, bill payments, and 16 | seamless NGN-USD transactions, EasySpend is solving some of Africa’s biggest 17 | financial challenges. From providing reliable virtual dollar cards for 18 | freelancers and remote workers to enabling businesses with bulk payment 19 | solutions, EasySpend is redefining how people move money. 20 | 21 | In creating the mobile applications for EasySpend they turned to Flutter to 22 | ensure that their customer base of over 100,000 active users have a consistent 23 | experience no matter what device they are using. For many Flutter developers, 24 | targeting multiple platforms is a key advantage of the framework. However, 25 | building and deploying iOS apps typically requires access to macOS, creating a 26 | barrier for developers who don’t own a Mac. This was the challenge faced by the 27 | team at EasySpend. 28 | 29 | > Being able to deploy to iOS without all of our developers using Mac’s removes 30 | > a significant hurdle for many developers like us 31 | > 32 | > - David Sylvester-Paul, CTO at EasySpend 33 | 34 | ## A Fully Remote Flutter Workflow 35 | 36 | By using services including Shorebird, David Sylvester-Paul, CTO at EasySpend, 37 | and his team have been able to deploy their Flutter application to iOS devices 38 | without all developers on their team owning a Mac. By leveraging Shorebird’s 39 | capabilities alongside other cloud-based tools, they bypassed the traditional 40 | Apple development constraints and successfully shipped their app across all the 41 | platforms that their customers are using. 42 | 43 | ## Seamless Multi-Platform Deployment 44 | 45 | By spending the engineering effort to integrate Codemagic with Shorebird they 46 | were able to create a mobile CI/CD pipeline that automatically pushes new 47 | builds, delivers patches, and significantly reduces deployment time. With all of 48 | this they have the flexibility to push out app changes on their schedule to 49 | ensure they are hitting their business objectives and customer needs. 50 | 51 | > In the past, we often wondered how other highly rated mobile apps updated 52 | > their features without forcing users to manually download an update from the 53 | > store. That curiosity led us to Shorebird, and ever since, we have implemented 54 | > it in all of our applications 55 | > 56 | > - David Sylvester-Paul, CTO at EasySpend 57 | 58 | With this approach, EasySpend supports multiple platforms—including iOS and 59 | Android—without over investing in cost prohibitive Apple hardware for an entire 60 | development team. This not only reduces development costs but also empowers more 61 | developers worldwide to build and distribute apps freely. 62 | 63 | > Shorebird made the process seamless, allowing me to focus on building great 64 | > apps rather than worrying about hardware limitations. 65 | > 66 | > - David Sylvester-Paul, CTO at EasySpend 67 | -------------------------------------------------------------------------------- /src/content/success-stories/kijiji.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Kijiji 3 | description: 4 | The leading Canadian online marketplace turned to Shorebird to ensure their 5 | customer base was up to date all the time. 6 | date: 2025-03-06 7 | cover: kijiji-cover.png 8 | highlights: 9 | [ 10 | 'Over 10 Million active users of the Kijiji mobile apps worldwide', 11 | '12 Million+ Shorebird patches installed to users in 2024', 12 | 'Approximately 68 days of review time saved in application deployment in 13 | 2024 by using Shorebird', 14 | ] 15 | --- 16 | 17 | 18 | 19 | Kijiji, a leading Canadian online marketplace, has been connecting millions of 20 | users for over a decade. With a focus on buying and selling new and used items, 21 | Kijiji has grown to host many wide-ranging product sections and boast a diverse 22 | user base, from power users to occasional buyers. With a large, dedicated user 23 | base, it’s critical that Kijiji’s website and mobile app remain user-friendly 24 | and maintain a high level of quality. 25 | 26 | ## Transition to Flutter 27 | 28 | Transitioning from a native app to Flutter three years ago, Kijiji’s revamped 29 | app launch went well, but the need for rapid and reliable updates became 30 | apparent. This was critically important in order to quickly react to user 31 | feedback as they were adjusting to the redesigned Flutter app. Maintaining a 32 | rigid release schedule with phased rollouts added complexity to addressing these 33 | urgent needs. This led the engineering team to look for a new tool to help solve 34 | their issues. 35 | 36 | ## Using Shorebird 37 | 38 | Kijiji integrated Shorebird into their development & deployment process, 39 | primarily for emergency "break glass" situations and critical fixes. The 40 | integration was straightforward, thanks to a collaboration with the Shorebird 41 | team. Kijiji’s implementation of Shorebird enabled a smooth deployment process 42 | for all of their mobile products. Shorebird empowered Kijiji to address user 43 | feedback and bugs swiftly, without disrupting their phased rollout schedule. 44 | 45 | > Our overall percentage of users running a buggy release is much lower after 46 | > incorporating Shorebird into our deployment process. Rather than waiting on 47 | > the stores to approve a release, and an operating system to actually execute 48 | > an update, we can know that our fixes are rolling out the second that we push 49 | > the button to deploy in Shorebird. 50 | > 51 | > - Scott MacDougall, Head of Engineering, Mobile at Kijiji 52 | 53 | ## Results 54 | 55 | The adoption of Shorebird has been transformative for Kijiji’s mobile app teams. 56 | The platform acts as a "code push insurance policy," allowing for rapid 57 | resolution of critical issues. This ability has minimized potential revenue 58 | losses and enhanced user experience. The current integration with Shorebird has 59 | solidified their app's stability and performance, which has allowed their Play 60 | Store rating to rise to 4.5 stars. 61 | 62 | Kijiji's partnership with Shorebird exemplifies how strategic tech integration 63 | can safeguard revenue and improve user satisfaction. As Kijiji looks to the 64 | future, Shorebird remains a pivotal part of their development strategy, ensuring 65 | they can continue to serve their vast user base effectively. 66 | 67 | > Over time, we have realized that we could Shorebird a fix quickly to all of 68 | > our users, which made an enormous impact on customer satisfaction. That’s now 69 | > become a default phrase in our development team, as it’s a great tool to have 70 | > in our toolbox. 71 | > 72 | > - Scott MacDougall, Head of Engineering, Mobile at Kijiji 73 | -------------------------------------------------------------------------------- /src/content/success-stories/solides.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Solides 3 | description: 4 | Hot fixes in minutes, not weeks. Learn how Solides transformed their mobile 5 | delivery with Shorebird. 6 | date: 2025-05-01 7 | cover: solides-cover.png 8 | highlights: 9 | [ 10 | 'Over 500,000 active users on the Solides Super App', 11 | '52 Releases with 26 patches across 3 separate apps in the first 6 months of 12 | using Shorebird', 13 | '~650,000 patches installed in the first 6 months of using Shorebird', 14 | ] 15 | --- 16 | 17 | At Solides, speed matters. As one of Brazil’s leading HR tech companies, Solides 18 | empowers businesses to manage their people more intelligently, with behavioral 19 | profiling, performance evaluations, HR analytics, time tracking, and vacation 20 | management solutions. Their mobile apps sit at the center of this strategy, 21 | connecting employees, managers, and HR teams with powerful tools that make work 22 | better. 23 | 24 | But as Solides grew, so did the pressure on their mobile release process. With 25 | hundreds of thousands of users relying on their flagship Solides App — a 26 | comprehensive “super app” for feedback, evaluations, and goal tracking — the 27 | traditional pace of app store reviews simply couldn’t keep up. Critical hot 28 | fixes could take days, sometimes even weeks, to reach users. In the fast-moving 29 | world of HR, that kind of delay wasn’t just inconvenient — it risked damaging 30 | user trust. 31 | 32 | “We were growing quickly, but the app release control over app stores was 33 | becoming slower and more complex,” said Solides’ Engineering Coordinator Pedro 34 | Afonso Ramos de Souza. “We needed a faster, more reliable way to deliver 35 | critical updates without being tied to store review timelines.” 36 | 37 | That search led them to Shorebird. 38 | 39 | ## Finding a Faster Path Forward 40 | 41 | Two years ago, the Solides team discovered Shorebird’s Code Push solution. They 42 | started cautiously, rolling out Shorebird to one of their secondary apps. It 43 | didn’t take long to see the difference. 44 | 45 | With Shorebird, Solides could deliver bug fixes and urgent updates in minutes or 46 | hours instead of waiting days. Confident in the results, they expanded Shorebird 47 | into their main Solides app, reaching over half a million users across Brazil. 48 | 49 | > Shorebird has been a game changer for us. We can now push critical updates 50 | > almost instantly. The experience for our users improved dramatically, and our 51 | > engineering team feels much more confident releasing new features. 52 | > 53 | > - Mairramer Veloso, Mobile Developer at Solides 54 | 55 | ## Turning Crisis into Confidence 56 | 57 | The real test came during a critical bug incident. Traditionally, resolving such 58 | an issue would have meant weeks of frustration for both the team and their 59 | users. With Shorebird, Solides was able to deploy three patches within two days, 60 | protecting user experience and preserving client trust — all while keeping 61 | development costs low. 62 | 63 | Today, Shorebird has become an essential part of Solides’ mobile strategy. They 64 | primarily use it to deliver bug fixes and minor updates — but they’re already 65 | working internally to expand its use even further, integrating Shorebird deeper 66 | into their full release cycle. 67 | 68 | > Our goal is to make Shorebird part of everything we do on mobile. It’s proven 69 | > itself. It’s helping us move faster, serve users better, and innovate with 70 | > confidence. 71 | > 72 | > - Pedro Afonso Ramos de Souza, Engineering Coordinator at Solides 73 | 74 | In the fast-paced world of HR tech, staying ahead requires more than just great 75 | ideas — it demands the ability to deliver them, instantly. Thanks to Shorebird, 76 | Solides is doing exactly that. 77 | -------------------------------------------------------------------------------- /src/layouts/main.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import '@/styles/global.css'; 3 | import config from '@/config'; 4 | export interface Props { 5 | title: string; 6 | } 7 | const { title } = Astro.props; 8 | const canonicalUrl = new URL(Astro.url.pathname, Astro.site); 9 | const coverUrl = new URL('/open-graph.png', Astro.url.origin); 10 | --- 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | {title} 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /src/layouts/markdown.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import '@/styles/global.css'; 3 | import { Navbar } from '@/components/ui/navbar'; 4 | import Footer from '@/components/ui/footer.astro'; 5 | 6 | const { frontmatter } = Astro.props; 7 | const { title, description } = frontmatter; 8 | const canonicalUrl = new URL(Astro.url.pathname, Astro.site); 9 | const coverUrl = new URL('/open-graph.png', Astro.url.origin); 10 | --- 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | {title} 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 50 | 51 | 52 | 53 |
56 | 57 |
58 |