diff --git a/.changeset/storage-bucket-project.md b/.changeset/storage-bucket-project.md
new file mode 100644
index 00000000..d280f9be
--- /dev/null
+++ b/.changeset/storage-bucket-project.md
@@ -0,0 +1,4 @@
+---
+"@blinkk/root-cms": minor
+---
+feat: add `storageConfig` option to support storage buckets in a different Firebase project.
diff --git a/docs/root.config.ts b/docs/root.config.ts
index 10358ac6..ac9b496f 100644
--- a/docs/root.config.ts
+++ b/docs/root.config.ts
@@ -42,6 +42,12 @@ export default defineConfig({
projectId: 'rootjs-dev',
storageBucket: 'rootjs-dev.appspot.com',
},
+ storageConfig: {
+ apiKey: 'AIzaSyDIoi6zECKeyJoCduYEmV5j9PIF-wbpaPo',
+ authDomain: 'rootjs-dev.firebaseapp.com',
+ projectId: 'rootjs-dev',
+ storageBucket: 'rootjs-dev.appspot.com',
+ },
gapi: {
apiKey: process.env.GAPI_API_KEY,
clientId: process.env.GAPI_CLIENT_ID,
diff --git a/examples/blog/root.config.ts b/examples/blog/root.config.ts
index 6b530cda..0da20938 100644
--- a/examples/blog/root.config.ts
+++ b/examples/blog/root.config.ts
@@ -64,6 +64,12 @@ export default defineConfig({
appId: '1:636169634531:web:7b8fe398f10e5d9c4e7bd6',
measurementId: 'G-5JTQHSPWBB',
},
+ storageConfig: {
+ apiKey: 'AIzaSyDIoi6zECKeyJoCduYEmV5j9PIF-wbpaPo',
+ authDomain: 'rootjs-dev.firebaseapp.com',
+ projectId: 'rootjs-dev',
+ storageBucket: 'rootjs-dev.appspot.com',
+ },
gapi: {
apiKey: process.env.GAPI_API_KEY,
clientId: process.env.GAPI_CLIENT_ID,
diff --git a/examples/cms/root.config.ts b/examples/cms/root.config.ts
index 82e06971..54499b86 100644
--- a/examples/cms/root.config.ts
+++ b/examples/cms/root.config.ts
@@ -34,6 +34,12 @@ export default defineConfig({
projectId: 'rootjs-dev',
storageBucket: 'rootjs-dev.appspot.com',
},
+ storageConfig: {
+ apiKey: 'AIzaSyDIoi6zECKeyJoCduYEmV5j9PIF-wbpaPo',
+ authDomain: 'rootjs-dev.firebaseapp.com',
+ projectId: 'rootjs-dev',
+ storageBucket: 'rootjs-dev.appspot.com',
+ },
gapi: {
apiKey: process.env.GAPI_API_KEY,
clientId: process.env.GAPI_CLIENT_ID,
diff --git a/packages/root-cms/core/app.tsx b/packages/root-cms/core/app.tsx
index 9ec6365d..0a148ab1 100644
--- a/packages/root-cms/core/app.tsx
+++ b/packages/root-cms/core/app.tsx
@@ -106,6 +106,7 @@ export async function renderApp(
},
},
firebaseConfig: cmsConfig.firebaseConfig,
+ storageConfig: cmsConfig.storageConfig,
gapi: cmsConfig.gapi,
collections: collections,
sidebar: cmsConfig.sidebar,
@@ -220,6 +221,7 @@ export async function renderSignIn(
const ctx = {
name: options.cmsConfig.name || options.cmsConfig.id || '',
firebaseConfig: options.cmsConfig.firebaseConfig,
+ storageConfig: options.cmsConfig.storageConfig,
};
const mainHtml = renderToString();
let html = `\n${mainHtml}`;
diff --git a/packages/root-cms/core/plugin.ts b/packages/root-cms/core/plugin.ts
index 94d92539..f836916e 100644
--- a/packages/root-cms/core/plugin.ts
+++ b/packages/root-cms/core/plugin.ts
@@ -59,6 +59,15 @@ export interface CMSSidebarTool {
iframeUrl?: string;
}
+export interface CMSFirebaseConfig {
+ [key: string]: string | undefined;
+ apiKey: string;
+ authDomain: string;
+ projectId: string;
+ storageBucket: string;
+ databaseId?: string;
+}
+
export type CMSPluginOptions = {
/**
* The ID of the project. Data will be stored under the namespace
@@ -76,14 +85,13 @@ export type CMSPluginOptions = {
* Firebase config object, which can be obtained in the Firebase Console by
* going to "Project Settings".
*/
- firebaseConfig: {
- [key: string]: string | undefined;
- apiKey: string;
- authDomain: string;
- projectId: string;
- storageBucket: string;
- databaseId?: string;
- };
+ firebaseConfig: CMSFirebaseConfig;
+
+ /**
+ * Optional Firebase config used for interacting with a storage bucket that
+ * exists in a different Firebase project.
+ */
+ storageConfig?: CMSFirebaseConfig;
/**
* GAPI credentials. Include if using Google Drive and Google Sheets features.
diff --git a/packages/root-cms/signin/signin.tsx b/packages/root-cms/signin/signin.tsx
index b97910fb..9744add6 100644
--- a/packages/root-cms/signin/signin.tsx
+++ b/packages/root-cms/signin/signin.tsx
@@ -11,6 +11,7 @@ declare global {
__ROOT_CTX: {
name: string;
firebaseConfig: Record;
+ storageConfig?: Record;
};
firebase: {
app: FirebaseApp;
diff --git a/packages/root-cms/ui/ui.tsx b/packages/root-cms/ui/ui.tsx
index 1eae0ea0..f08182c7 100644
--- a/packages/root-cms/ui/ui.tsx
+++ b/packages/root-cms/ui/ui.tsx
@@ -1,7 +1,7 @@
import {MantineProvider} from '@mantine/core';
import {ModalsProvider} from '@mantine/modals';
import {NotificationsProvider} from '@mantine/notifications';
-import {initializeApp} from 'firebase/app';
+import {initializeApp, getApp} from 'firebase/app';
import {User, getAuth} from 'firebase/auth';
import {initializeFirestore} from 'firebase/firestore';
import {getStorage} from 'firebase/storage';
@@ -66,6 +66,7 @@ declare global {
};
};
firebaseConfig: Record;
+ storageConfig?: Record;
gapi?: {
apiKey: string;
clientId: string;
@@ -169,6 +170,14 @@ function loginRedirect() {
}
const app = initializeApp(window.__ROOT_CTX.firebaseConfig);
+let storageApp = app;
+if (window.__ROOT_CTX.storageConfig) {
+ try {
+ storageApp = initializeApp(window.__ROOT_CTX.storageConfig, 'storage');
+ } catch (err) {
+ storageApp = getApp('storage');
+ }
+}
const databaseId = window.__ROOT_CTX.firebaseConfig.databaseId || '(default)';
// const db = getFirestore(app);
// NOTE(stevenle): the firestore web channel rpc sometimes has issues in
@@ -184,7 +193,7 @@ const db = initializeFirestore(
databaseId
);
const auth = getAuth(app);
-const storage = getStorage(app);
+const storage = getStorage(storageApp);
auth.onAuthStateChanged((user) => {
if (!user) {
loginRedirect();