Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 36 additions & 13 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,18 +1,41 @@
/packages/**/*/dist/
/examples/
/dist
/packages/@apphosting/publish-dev/.local
/packages/@apphosting/publish-dev/htpasswd
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# NPM
node_modules
# dependencies
/node_modules
/.pnp
.pnp.js
/patches

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.vscode
*.log
.DS_Store
/apphosting-*.tgz
/firebase-frameworks-*.tgz
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lint-staged.config.js

# local env files
.env.local
.env.development.local
.env.test.local
.env.production.local
.env

# vercel
.vercel

# firebase
.firebase
# typescript
*.tsbuildinfo
next-env.d.ts
44 changes: 44 additions & 0 deletions .idx/dev.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# To learn more about how to use Nix to configure your environment
# see: https://firebase.google.com/docs/studio/customize-workspace
{pkgs}: {
# Which nixpkgs channel to use.
channel = "stable-24.11"; # or "unstable"
# Use https://search.nixos.org/packages to find packages
packages = [
pkgs.nodejs_20
pkgs.zulu
];
# Sets environment variables in the workspace
env = {};
# This adds a file watcher to startup the firebase emulators. The emulators will only start if
# a firebase.json file is written into the user's directory
services.firebase.emulators = {
# Disabling because we are using prod backends right now
detect = false;
projectId = "demo-app";
services = ["auth" "firestore"];
};
idx = {
# Search for the extensions you want on https://open-vsx.org/ and use "publisher.id"
extensions = [
# "vscodevim.vim"
];
workspace = {
onCreate = {
default.openFiles = [
"src/app/page.tsx"
];
};
};
# Enable previews and customize configuration
previews = {
enable = true;
previews = {
web = {
command = ["npm" "run" "dev" "--" "--port" "$PORT" "--hostname" "0.0.0.0"];
manager = "web";
};
};
};
};
}
Binary file added .idx/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file added .modified
Empty file.
174 changes: 3 additions & 171 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,173 +1,5 @@
# App Hosting adapters
# Firebase Studio

## Overview
This is a NextJS starter in Firebase Studio.

App Hosting provides configuration-free build and deploy support for Web apps developed in these frameworks:

* Next.js 13+
* Angular 17.2+

This repo holds the code for the adapters that enable support for these frameworks. At a high level these adapters transform framework specific configurations into an [output bundle spec](#app-hosting-output-bundle) that App Hosting can use to configure frameworks support. For more information see [Framework integration](https://firebase.google.com/docs/app-hosting/about-app-hosting#frameworks).

## App Hosting output bundle

The App Hosting output bundle is a file based specification that allows different frameworks to configure and customize their App Hosting deployment for enhanced support.

Any framework that can generate a build output in accordance with the App Hosting output bundle can be deployed on App Hosting.

The output bundle primarily consists of a `bundle.yaml` file that sits inside of the `.apphosting` directory. This bundle.yaml contains all the ways that frameworks can configure App Hosting when users deploy their applications.

> [!NOTE]
> App Hosting technically supports all node applications, but no custom framework features will be enabled without the output bundle.

## Output bundle Schema

The output bundle is contained in a single file:

```shell
.apphosting/bundle.yaml
```

As long as this file exists and follows the schema, App Hosting will be able to process the build properly.

The schema can also be found in [source](https://github.com/FirebaseExtended/firebase-framework-tools/blob/main/packages/%40apphosting/common/src/index.ts#L4)

```typescript
interface OutputBundle {
version: "v1"
runConfig: RunConfig;
metadata: Metadata;
outputFiles?: OutputFiles;
}
```

### Version

The `version` represents which output bundle version is currently being used. The current version is v1.

### RunConfig

The `runConfig` fields configures the Cloud Run service associated with the App Hosting Backend.

```typescript
interface RunConfig {
runCommand: string;
environmentVariables?: EnvVarConfig[];
concurrency?: number;
cpu?: number;
memoryMiB?: number;
minInstances?: number;
maxInstances?: number;
}
```

| Field | Type | Description | Required? |
| ---------- | ------- | - | - |
| `runCommand` | `string` |Command to start the server (e.g. `node dist/index.js`). Assume this command is run from the root dir of the workspace. This should be the productionized version of the server start command. | y |
| `environmentVariables`| `EnvVarConfig[]` | Environment variables present in the server execution environment.| n |
| `concurrency` | `number` | The maximum number of concurrent requests that each server instance can receive.| n |
| `cpu` | `number` |The number of CPUs used in a single server instance. | n |
| `memoryMiB` | `number` | The amount of memory available for a server instance.| n |
| `minInstance` | `number` |The limit on the minimum number of function instances that may coexist at a given time. | n |
| `MaxInstance` | `number` | The limit on the maximum number of function instances that may coexist at a given time.| n |

Many of these fields are shared with `apphosting.yaml`. See the [runConfig reference documentation](https://firebase.google.com/docs/reference/apphosting/rest/v1beta/projects.locations.backends.builds#runconfig) for additional context and default values.

### EnvVarConfig

```typescript
interface EnvVarConfig {
variable: string;
value: string;
availability: 'RUNTIME'
}

```

| Field | Type | Description | Required? |
| ---------- | ------- | - | - |
| `variable` | `string` |Name of the environment variable | y |
| `value` | `string` |Value associated with the environment variable | y |
| `availability` | `RUNTIME` | Where the variable will be available. For now this will always be `RUNTIME` | y |

### Metadata

```typescript
interface Metadata {
adapterPackageName: string;
adapterVersion: string;
framework: string;
frameworkVersion?: string;
}

```

| Field | Type | Description | Required? |
| ---------- | ------- | - | - |
| `adapterPackageName` | `string` |Name of the adapter (this should be the npm package name) | y |
| `adapterVersion`| `string` | Version of the adapter | y |
| `framework` | `string` | Name of the framework that is being supported | y |
| `frameworkVersion` | `string` |Version of the framework that is being supported | n |

### OutputFiles

OutputFiles is an optional field to configure outputFiles and optimize server files + static assets.

```typescript
interface OutputFiles {
serverApp: ServerApp
}

```

| Field | Type | Description | Required? |
| ---------- | ------- | - | - |
| `serverApp` | `ServerApp` | ServerApp holds configurations related to the serving files at runtime from Cloud Run | y |

### ServerApp

OutputFiles is an optional field to configure outputFiles and optimize server files + static assets.

```typescript
interface ServerApp {
include: string[]
}

```

| Field | Type | Description | Required? |
| ---------- | ------- | - | - |
| `include` | `string[]` | include holds a list of directories + files relative to the app root dir that frameworks need to deploy to the App Hosting server, generally this will be the output/dist directory (e.g. .output or dist). In the case that the framework wants to include all files they can use [“.”] | y |

## Sample

Here is a sample `.apphosting/bundle.yaml` file putting all this together:

```yaml
version: v1
runConfig:
runCommand: node dist/index.js
environmentVariables:
- variable: VAR
value: 8080
availability: RUNTIME
concurrency: 80
cpu: 2
memoryMiB: 512
minInstances: 0
maxInstances: 14

outputFiles:
serverApp:
include:
- dist
- .output

metadata:
adapterPackageName: npm-name
adapterVersion: 12.0.0
framework: framework-name
frameworkVersion: 1.0.0
```

As long as you have the `bundle.yaml` in this format, App Hosting will be able to deploy any framework that supports server side rendering.
To get started, take a look at src/app/page.tsx.
7 changes: 7 additions & 0 deletions apphosting.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Settings to manage and configure a Firebase App Hosting backend.
# https://firebase.google.com/docs/app-hosting/configure

runConfig:
# Increase this value if you'd like to automatically spin up
# more instances in response to increased traffic.
maxInstances: 2
21 changes: 21 additions & 0 deletions components.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "default",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "tailwind.config.ts",
"css": "src/app/globals.css",
"baseColor": "neutral",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"iconLibrary": "lucide"
}
Binary file added download.zip
Binary file not shown.
13 changes: 13 additions & 0 deletions firestore.rules
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
rules_version = '2';

service cloud.firestore {
match /databases/{database}/documents {
// This single block grants a user full access to their own document
// and everything inside it (all subcollections and their documents).
// The {path=**} is a recursive wildcard that matches any document or
// subcollection under /users/{userId}, including the user document itself.
match /users/{userId}/{path=**} {
allow read, write: if request.auth.uid == userId;
}
}
}
35 changes: 35 additions & 0 deletions next.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@

import type {NextConfig} from 'next';

const nextConfig: NextConfig = {
typescript: {
ignoreBuildErrors: true,
},
eslint: {
ignoreDuringBuilds: true,
},
Comment on lines +5 to +10

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

Disabling TypeScript and ESLint checks during the build process is highly discouraged for production applications. This can lead to deploying code with type errors or linting issues, which can cause runtime errors and make the codebase harder to maintain. It's recommended to enable these checks to ensure code quality and stability.

Suggested change
typescript: {
ignoreBuildErrors: true,
},
eslint: {
ignoreDuringBuilds: true,
},
typescript: {
ignoreBuildErrors: false,
},
eslint: {
ignoreDuringBuilds: false,
},

images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'placehold.co',
port: '',
pathname: '/**',
},
{
protocol: 'https',
hostname: 'images.unsplash.com',
port: '',
pathname: '/**',
},
{
protocol: 'https',
hostname: 'picsum.photos',
port: '',
pathname: '/**',
},
],
},
};

export default nextConfig;
Loading