diff --git a/packages/backend-core/src/objectStore/index.ts b/packages/backend-core/src/objectStore/index.ts
index fe9be90659..774018b6df 100644
--- a/packages/backend-core/src/objectStore/index.ts
+++ b/packages/backend-core/src/objectStore/index.ts
@@ -178,6 +178,14 @@ export const streamUpload = async (
const objectStore = ObjectStore(bucketName)
await makeSureBucketExists(objectStore, bucketName)
+ // Set content type for certain known extensions
+ if (filename?.endsWith(".js")) {
+ extra = {
+ ...extra,
+ ContentType: "application/javascript",
+ }
+ }
+
const params = {
Bucket: sanitizeBucket(bucketName),
Key: sanitizeKey(filename),
diff --git a/packages/builder/src/builderStore/store/frontend.js b/packages/builder/src/builderStore/store/frontend.js
index 7903210f53..16d16de8a2 100644
--- a/packages/builder/src/builderStore/store/frontend.js
+++ b/packages/builder/src/builderStore/store/frontend.js
@@ -90,36 +90,14 @@ export const getFrontendStore = () => {
// Fetch component definitions.
// Allow errors to propagate.
- let components = await API.fetchComponentLibDefinitions(application.appId)
-
- // Extend definitions with custom components
- components["test"] = {
- component: "test",
- name: "Super cool component",
- icon: "Text",
- description: "A custom component",
- showSettingsBar: false,
- hasChildren: true,
- settings: [
- {
- type: "text",
- key: "text",
- label: "Text",
- },
- ],
- context: {
- type: "static",
- values: [
- {
- label: "Text prop",
- key: "text",
- },
- ],
- },
- }
+ const components = await API.fetchComponentLibDefinitions(
+ application.appId
+ )
// Filter out custom component keys so we can flag them
- let customComponents = ["test"]
+ const customComponents = Object.keys(components).filter(name =>
+ name.startsWith("plugin/")
+ )
// Reset store state
store.update(state => ({
@@ -146,6 +124,7 @@ export const getFrontendStore = () => {
version: application.version,
revertableVersion: application.revertableVersion,
navigation: application.navigation || {},
+ usedPlugins: application.usedPlugins || [],
}))
// Initialise backend stores
diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/AppPreview.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/AppPreview.svelte
index 3c99c90d49..cd86d2e87c 100644
--- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/AppPreview.svelte
+++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/AppPreview.svelte
@@ -41,10 +41,23 @@
}
// Construct iframe template
- $: template = iframeTemplate.replace(
- /\{\{ CLIENT_LIB_PATH }}/,
- $store.clientLibPath
- )
+ $: pluginLinks = generatePluginLinks($store.usedPlugins)
+ $: template = iframeTemplate
+ .replace(/\{\{ CLIENT_LIB_PATH }}/, $store.clientLibPath)
+ .replace(/\{\{ PLUGINS }}/, pluginLinks)
+
+ const generatePluginLinks = plugins => {
+ if (!plugins?.length) {
+ return ""
+ }
+ return plugins
+ .map(plugin => {
+ // Split up like this as otherwise parsing fails because the script
+ // tags confuse svelte
+ return `<` + `script src="/plugins/${plugin.jsUrl}">` + `script>`
+ })
+ .join("")
+ }
const placeholderScreen = new Screen()
.name("Screen Placeholder")
@@ -92,6 +105,7 @@
? [$store.componentToPaste?._id]
: [],
isBudibaseEvent: true,
+ usedPlugins: $store.usedPlugins,
}
// Refresh the preview when required
diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/iframeTemplate.js b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/iframeTemplate.js
index 64a05c7246..2b24ee4fa0 100644
--- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/iframeTemplate.js
+++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/iframeTemplate.js
@@ -37,9 +37,7 @@ export default `
}
-
+ {{ PLUGINS }}
@@ -85,9 +86,13 @@
-
+ {#if usedPlugins?.length}
+ {#each usedPlugins as plugin}
+
+ {/each}
+ {/if}