<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Nocodetalks - Bubble.io Newsletter]]></title><description><![CDATA[Bubble .io Coach | No-Code Content Creator]]></description><link>https://blog.nocodetalks.co</link><generator>RSS for Node</generator><lastBuildDate>Wed, 22 Apr 2026 02:37:29 GMT</lastBuildDate><atom:link href="https://blog.nocodetalks.co/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Capturing hover effects that only exist in JavaScript (Puppeteer + MutationObserver)]]></title><description><![CDATA[Most websites use CSS :hover for hover effects. You can see them in the stylesheet, copy them, move on.

Framer doesn't do that.

Framer uses a React animation library (Framer Motion) with a whileHove]]></description><link>https://blog.nocodetalks.co/capturing-hover-effects-that-only-exist-in-javascript-puppeteer-mutationobserver</link><guid isPermaLink="true">https://blog.nocodetalks.co/capturing-hover-effects-that-only-exist-in-javascript-puppeteer-mutationobserver</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[webdev]]></category><category><![CDATA[puppeteer]]></category><category><![CDATA[CSS]]></category><dc:creator><![CDATA[Ankur Khandelwal]]></dc:creator><pubDate>Sun, 15 Mar 2026 07:34:05 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/64883d1e4e0ced17f444a89b/9f51ad43-d4ac-4359-9339-7fce60f0b323.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Most websites use CSS <code>:hover</code> for hover effects. You can see them in the stylesheet, copy them, move on.</p>
<blockquote>
<p>Framer doesn't do that.</p>
</blockquote>
<p>Framer uses a React animation library (Framer Motion) with a <code>whileHover</code> prop. When you mouse over an element, JavaScript calls <code>element.style.setProperty()</code> to apply inline styles in real time. When you mouse away, it reverts them. There's no CSS rule. The hover state only exists while your mouse is physically over the element, enforced by JS.</p>
<p>I ran into this while building an export tool for Framer sites (<a href="https://letaiworkforme.com">letaiworkforme.com</a>). The exported pages had no hover effects at all because the React runtime was stripped out. Buttons didn't change color. Cards didn't lift on hover. The site felt dead.</p>
<p>I needed a way to capture these runtime hover styles and convert them into real CSS <code>:hover</code> rules. Here's how I did it.</p>
<h2>The setup</h2>
<p>The tool uses Puppeteer (headless Chrome) to crawl Framer sites. After loading a page, it strips out React's hydration scripts and replaces interactive components with vanilla JS. But hover effects need to be captured BEFORE stripping React, while the runtime is still active.</p>
<p>The properties I care about capturing:</p>
<pre><code class="language-javascript"> const HOVER_PROPS = [ 
          'background-color', 'color', 'opacity', 'transform', 'box-shadow', 'border-color', 'border-radius', 'filter', 'scale', 'text-decoration-color', 
]; 
</code></pre>
<p>These cover 95% of what Framer sites animate on hover.</p>
<h3>Step 1: Find hover candidates</h3>
<p>Framer marks elements that have hover animations with <code>data-highlight="true"</code>. This is how their own runtime knows which elements to watch for pointer events.</p>
<pre><code class="language-javascript">const candidates = document.querySelectorAll('[data-highlight="true"]');  
</code></pre>
<p>I filter out anything smaller than 5x5 pixels (invisible or decorative elements), sort by vertical position (top to bottom, so the mouse path is natural), and cap at 60 elements per page. More than that and the capture time gets too long.</p>
<h3>Step 2: Snapshot the baseline</h3>
<p>Before hovering over anything, I park the mouse at <code>(0, 0)</code> to make sure nothing is in a hover state. Then for each candidate, I record the current inline style values for all the properties I care about:</p>
<pre><code class="language-javascript">const baseline = {}; 
for (const prop of HOVER_PROPS) { 
baseline[prop] = el.style.getPropertyValue(prop); 
} 
</code></pre>
<p>This gives me the "before" state. Whatever changes after hovering is the hover effect.</p>
<h3>Step 3: Set up MutationObserver before hovering</h3>
<p>This is the part that took the most iteration. I set up a <code>MutationObserver</code> on the element's parent BEFORE moving the mouse. The observer watches for <code>style</code> and <code>class</code> attribute changes on all descendants:</p>
<pre><code class="language-javascript">const mutatedEls = new Set(); 
let classChanged = false; 

const obs = new MutationObserver((muts) =&gt; { 
    for (const m of muts) { 
        if (m.attributeName === 'style') { 
            mutatedEls.add(m.target); 
        } 
        if (m.attributeName === 'class' &amp;&amp; m.target === el) { 
            classChanged = true; 
        } 
       } 
     }); 

obs.observe(parentElement, { 
    attributes: true, 
    attributeFilter: ['style', 'class'], 
    subtree: true, 
}); 
</code></pre>
<p>Why track mutation counts? Because I need to distinguish between two very different things:</p>
<p>1. <strong>A real hover effect</strong> (the element itself changes <code>background-color</code>, <code>box-shadow</code>, etc.)<br />2. <strong>A variant transition</strong> (the hover triggers a full layout swap, with 20-40 child elements all changing at once)</p>
<p>If more than 5 child elements mutate during hover, it's probably a variant transition (handled by CSS class swaps, not inline styles). I skip those and handle them differently.</p>
<h3>Step 4: Move the mouse with CDP</h3>
<p>I use Puppeteer's <code>page.mouse.move()</code> which dispatches real mouse events through Chrome DevTools Protocol. This triggers Framer Motion's gesture detection the same way a real user's mouse would:</p>
<pre><code class="language-javascript">await page.mouse.move(centerX, centerY); // Wait 350ms for the spring animation to settle 
await new Promise(r =&gt; setTimeout(r, 350)); 
</code></pre>
<p>The 350ms wait is important. Framer Motion uses spring-based animations, so the hover state doesn't apply instantly. It eases in over 200-300ms. If you check too early, you get intermediate values instead of the final state.</p>
<h3>Step 5: Diff the styles</h3>
<p>After the animation settles, I compare each property against the baseline:</p>
<pre><code class="language-javascript">const changed = {}; 
for (const prop of HOVER_PROPS) { 
    const val = el.style.getPropertyValue(prop); 
    if (val &amp;&amp; val !== baseline[prop]) { 
        changed[prop] = val; 
    } 
} 
</code></pre>
<p>If <code>background-color</code> went from <code>""</code> to <code>"rgb(59, 130, 246)"</code>, that's a hover effect. If nothing changed, the element doesn't have a real hover animation (maybe <code>data-highlight</code> was set for a different reason).</p>
<h3>Step 6: Verify by un-hovering</h3>
<p>This is the step that catches false positives. I move the mouse away and check if the styles revert:</p>
<pre><code class="language-javascript">await page.mouse.move(0, 0); 
await new Promise(r =&gt; setTimeout(r, 350)); 
let reverted = 0; 
for (const prop of Object.keys(changed)) { 
    if (el.style.getPropertyValue(prop) !== changed[prop]) { 
        reverted++; 
    } 
} 

if (reverted === 0) return false; // not a hover effect
</code></pre>
<p>If the styles DON'T revert, it wasn't a hover effect. It was a click handler, a state change, or some other one-time mutation. This verification step filters out about 15% of false positives on a typical Framer site.</p>
<h3>Step 7: Convert to CSS :hover rules</h3>
<p>Once I have the verified hover properties, I store them as data attributes on the element:</p>
<pre><code class="language-javascript">el.setAttribute('data-framer-hover-id', 'fh42'); 
el.setAttribute('data-framer-hover-self', JSON.stringify(changed)); 
</code></pre>
<p>Later, the URL rewriter reads these attributes and generates real CSS:</p>
<pre><code class="language-css">[data-framer-hover-id="fh42"]:hover { 
    background-color: rgb(59, 130, 246); 
    box-shadow: 0 4px 12px rgba(0,0,0,0.15); 
    transition: all 0.2s ease; 
} 
</code></pre>
<p>The <code>transition</code> is added so the hover doesn't snap on/off. Framer Motion uses spring animations for hover, but a CSS <code>ease</code> transition is close enough for exported sites.</p>
<h2>The third type: CSS variant hovers</h2>
<p>Beyond inline-style hovers, Framer has a second hover mechanism that works through CSS class swaps. When hovering, Framer swaps a class like <code>framer-v-abc123</code> to <code>framer-v-xyz789</code>. Each class points to a different set of CSS rules already in the stylesheet.</p>
<p>The MutationObserver catches this because it also watches for <code>class</code> attribute changes. When I detect a <code>framer-v-*</code> class swap during hover:</p>
<ol>
<li><p>Record the base class and the hover class</p>
</li>
<li><p>Move mouse away and verify the class reverts to the base</p>
</li>
<li><p>Store both class names as data attributes</p>
</li>
<li><p>The rewriter then generates a CSS rule that swaps classes on <code>:hover</code></p>
</li>
</ol>
<p>This handles hover effects that change layout, typography, or anything too complex for inline style manipulation.</p>
<h2>Numbers</h2>
<p>On a typical Framer site with 30-40 hoverable elements:</p>
<ul>
<li><p>Capture time: 15-25 seconds (350ms per element for hover + 350ms for un-hover + overhead)</p>
</li>
<li><p>Inline style hovers detected: 5-15</p>
</li>
<li><p>Variant hovers detected: 2-8</p>
</li>
<li><p>False positives filtered by revert check: 3-6</p>
</li>
<li><p>Generated CSS rules: 10-20</p>
</li>
</ul>
<h2>What I'd do differently</h2>
<p>The 350ms wait per element is the biggest bottleneck. I could batch elements that are far apart on the page and hover them in parallel (one mouse can only be in one place, but elements that don't overlap could theoretically be tested concurrently with separate CDP sessions). Haven't tried this yet.</p>
<p>I also considered using <code>getComputedStyle()</code> instead of reading inline style properties. The problem is <code>getComputedStyle</code> includes inherited and stylesheet styles, making the diff noisy. Inline <code>style.getPropertyValue()</code> only returns what JavaScript explicitly set, which is exactly what Framer Motion does.</p>
<hr />
<blockquote>
<p>The full crawler is part of <a href="https://letaiworkforme.com">FramerExport</a>, which exports Framer sites to static HTML/CSS/JS. The hover capture is about 200 lines of the ~1,100 line crawler.</p>
</blockquote>
<p>If you've run into similar problems with capturing runtime-generated styles, I'd like to hear what approach you took.</p>
]]></content:encoded></item><item><title><![CDATA[Is Moving to Xano the Right Choice for Your Project?]]></title><description><![CDATA[https://www.youtube.com/watch?v=63Lkpw8fGAw
 
Introduction to Xano: A No-Code Backend Solution
When it comes to choosing the right backend service for your project, Xano emerges as a noteworthy contender. This video explores the various facets of Xan...]]></description><link>https://blog.nocodetalks.co/is-moving-to-xano-the-right-choice-for-your-project</link><guid isPermaLink="true">https://blog.nocodetalks.co/is-moving-to-xano-the-right-choice-for-your-project</guid><category><![CDATA[XANO]]></category><category><![CDATA[backend]]></category><category><![CDATA[backend developments]]></category><category><![CDATA[Backend Development]]></category><dc:creator><![CDATA[Ankur Khandelwal]]></dc:creator><pubDate>Tue, 16 Apr 2024 04:49:31 GMT</pubDate><content:encoded><![CDATA[<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://www.youtube.com/watch?v=63Lkpw8fGAw">https://www.youtube.com/watch?v=63Lkpw8fGAw</a></div>
<p> </p>
<h2 id="heading-introduction-to-xano-a-no-code-backend-solution"><strong>Introduction to Xano: A No-Code Backend Solution</strong></h2>
<p>When it comes to choosing the right backend service for your project, Xano emerges as a noteworthy contender. This video explores the various facets of Xano, addressing common queries about its benefits and whether it's the right fit for your needs. Before we dive into the specifics, it's crucial to understand what Xano is. Unlike traditional no-code databases, Xano serves as a comprehensive no-code backend service, catering to the needs of both backend and frontend developers. It simplifies complex backend tasks, such as database interaction, API building, and server management, without requiring additional DevOps personnel.</p>
<h3 id="heading-key-features-of-xano"><strong>Key Features of Xano</strong></h3>
<p>Xano stands out with its robust feature set designed to streamline backend development:</p>
<ul>
<li><p><strong>Microservice Architecture</strong>: Xano supports distributing your application across multiple servers, enhancing scalability and performance.</p>
</li>
<li><p><strong>Middleware Support</strong>: It allows the implementation of common logic across APIs, such as user blocking or validation checks, although some features like IP restrictions are awaiting future updates.</p>
</li>
<li><p><strong>Geographical Server Location</strong>: Essential for applications with specific regulatory requirements, Xano offers server location flexibility even in its basic plan, a significant advantage over competitors like Bubble.</p>
</li>
<li><p><strong>Load Balancing and On-premise Hosting</strong>: Xano’s load balancer efficiently distributes traffic across servers. Additionally, it supports on-premise hosting for enterprises with strict data control needs.</p>
</li>
<li><p><strong>Database and DevOps Features</strong>: From direct database access using PostgreSQL to handling DevOps issues like rate limiting and load balancing, Xano covers all bases, making it a truly comprehensive backend solution.</p>
</li>
<li><p><strong>Data Caching and Static IP Addresses</strong>: Enhance your application’s performance with Xano’s data caching capabilities and secure it with a static IP address for whitelist security protocols.</p>
</li>
</ul>
<h3 id="heading-why-xano-may-be-the-right-move"><strong>Why Xano May Be the Right Move</strong></h3>
<p>Moving to Xano isn't just about reducing workload units (when it comes to moving Bubble app to Xano); it's about leveraging a platform that offers substantial backend capabilities at a fixed price. If your project requires any of the sophisticated features mentioned above, Xano provides a cost-effective and powerful alternative to platforms like Bubble, especially for applications demanding high performance and specific compliance standards.</p>
<h3 id="heading-considerations-before-making-the-switch"><strong>Considerations Before Making the Switch</strong></h3>
<p>However, the decision to switch should not be made lightly. Xano presents a learning curve that might be steeper for individuals without a technical background. Moreover, transitioning a complex application from another platform to Xano involves significant time and effort, which could negate the initial cost benefits. Additionally, Xano's current limitations in plugin and library support could be a deal-breaker for projects relying heavily on these resources.</p>
<h3 id="heading-conclusion-weighing-the-pros-and-cons"><strong>Conclusion: Weighing the Pros and Cons</strong></h3>
<p>Xano offers compelling features for backend development, from microservices to direct database access and beyond. Yet, it's essential to consider your project's specific needs, the potential learning curve, and the effort required for migration. Xano shines for projects that can fully utilize its backend capabilities without being hindered by its current limitations. As with any technological decision, a careful evaluation of your requirements and Xano's offerings will guide you to the right choice.</p>
<p>If you have any questions or need further clarification or looking to build project on Xano- mail me your requirement at <strong>nocodetalks@gmail.com</strong> .</p>
]]></content:encoded></item><item><title><![CDATA[Launching Xano Cohort Program]]></title><description><![CDATA[Hi Everyone,  
This newsletter will be a little different from the ones before. In this edition, I'm excited to launch the Xano Cohort program, which I will be running. The program will start on May 6th for 6 weeks.
Why I am starting this:
Whenever I...]]></description><link>https://blog.nocodetalks.co/launching-xano-cohort-program</link><guid isPermaLink="true">https://blog.nocodetalks.co/launching-xano-cohort-program</guid><category><![CDATA[XANO]]></category><category><![CDATA[Full Stack Development]]></category><category><![CDATA[backend]]></category><category><![CDATA[backend developments]]></category><dc:creator><![CDATA[Ankur Khandelwal]]></dc:creator><pubDate>Fri, 12 Apr 2024 13:50:29 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1712917479351/c724b34a-fe7b-4902-9956-cb54aa055e92.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hi Everyone,  </p>
<p>This newsletter will be a little different from the ones before. In this edition, I'm excited to launch the <a target="_blank" href="https://www.nocodetalks.co/learnxano">Xano Cohort program</a>, which I will be running. The program will start on May 6th for 6 weeks.</p>
<h3 id="heading-why-i-am-starting-this"><strong>Why I am starting this:</strong></h3>
<p>Whenever I talk to people about Xano, the first thing they mention is the <strong>scarcity of content</strong> that focuses on building with Xano, as opposed to merely listing its features, similar to the wealth of tutorials available for Bubble. So, I thought, why not solve this problem?</p>
<p>In February, I ran the first batch with six participants, and all of them found it quite useful. Two out of six actually migrated their live Bubble apps to Xano and were happy about the switch. Two participants are exploring freelancing gigs, and the remaining two are building software using Xano. Therefore, I thought, let's scale this up a bit this time (for the current batch, I am opening 15 seats).</p>
<h3 id="heading-why-a-cohort-not-a-course"><strong>Why a cohort, not a course?</strong></h3>
<p>I want to <strong>engage with people</strong> who have the time to commit. Xano has a steep learning curve, so I'm looking for participants who can dedicate at least 7-10 hours a week to practice actively. This is something I cannot ensure if I merely offered a course. In the past, when I taught <a target="_blank" href="https://store.nocodetalks.co/l/bubble-plugin">Bubble plugin building</a>, it was unclear who actually built any plugins using my course. Consequently, the course became a black box, with no feedback loop. People would buy it and hardly watch it, let alone build anything.</p>
<h3 id="heading-who-is-this-cohort-for"><strong>Who is this cohort for?</strong></h3>
<ul>
<li><p>Those who know a frontend programming language and want to become full-stack developers.</p>
</li>
<li><p>Those who have built products on <a target="_blank" href="http://Bubble.io">Bubble.io</a> and want to migrate their backend to Xano.</p>
</li>
<li><p>No-code freelancers who want to learn new skills.</p>
</li>
</ul>
<h3 id="heading-what-will-be-the-final-outcome"><strong>What will be the final outcome?</strong></h3>
<ul>
<li><p>Learn how to build a scalable backend using Xano.</p>
</li>
<li><p>Learn to design efficient database structures.</p>
</li>
<li><p>You will complete the program with two projects.</p>
</li>
<li><p>Live QA sessions each week along with discord group.</p>
</li>
</ul>
<p>Let me know if you are interested or someone in your circle interested. </p>
<p>For more details, check out <a target="_blank" href="https://www.nocodetalks.co/learnxano">here</a></p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://www.nocodetalks.co/learnxano">https://www.nocodetalks.co/learnxano</a></div>
]]></content:encoded></item><item><title><![CDATA[Mastering Workload Units in Bubble: Strategies for Efficiency]]></title><description><![CDATA[Learn what workload units are in Bubble, how they are calculated, and discover actionable strategies to optimize and reduce your app's workload units for better performance and cost efficiency.

One think before moving forward- If you are reading thi...]]></description><link>https://blog.nocodetalks.co/mastering-workload-units-in-bubble</link><guid isPermaLink="true">https://blog.nocodetalks.co/mastering-workload-units-in-bubble</guid><category><![CDATA[Workload units]]></category><category><![CDATA[bubble.io]]></category><category><![CDATA[cost-optimisation]]></category><category><![CDATA[cost]]></category><dc:creator><![CDATA[Ankur Khandelwal]]></dc:creator><pubDate>Tue, 06 Feb 2024 16:50:20 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1707237390793/5578a11f-4273-4c6d-95b1-bec36e61a5e4.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Learn what workload units are in Bubble, how they are calculated, and discover actionable strategies to optimize and reduce your app's workload units for better performance and cost efficiency.</p>
<hr />
<p><strong>One think before moving forward</strong>- If you are reading this post in your email, you must have subscribed to the Bubble Weekly Newsletter. That's why you are receiving this email. If you don't want to continue getting these emails, you can unsubscribe it.</p>
<hr />
<p>Watch Video if you prefer-</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://www.youtube.com/watch?v=1iblvdntwHU">https://www.youtube.com/watch?v=1iblvdntwHU</a></div>
<p> </p>
<h2 id="heading-understanding-workload-units-in-bubble"><strong>Understanding Workload Units in Bubble</strong></h2>
<p>In the world of Bubble.io, a popular no-code platform, understanding and managing workload units is crucial for optimizing app performance and managing costs. Workload units are a measure of the computational resources consumed by your app on Bubble's servers. Just like you measure weight in pounds or kilograms, Bubble measures the computational work in workload units.</p>
<h3 id="heading-the-concept-of-workload-units"><strong>The Concept of Workload Units</strong></h3>
<p>Think of workload units as a way to gauge the stress your application puts on Bubble's servers. This measurement is directly tied to Bubble's pricing structure, making it essential for developers to monitor and manage their app's workload units efficiently.</p>
<h3 id="heading-why-workload-units-matter"><strong>Why Workload Units Matter</strong></h3>
<p>Every action your app performs, from database modifications to API calls, consumes a certain number of workload units. These units are a reflection of the server resources required to execute these actions. Bubble offers a transparent overview of how much each action consumes, but the calculation is not always straightforward.</p>
<h3 id="heading-how-workload-units-are-calculated"><strong>How Workload Units Are Calculated</strong></h3>
<p>Consider booking a luxury hotel room as an analogy. The advertised cost is not the only expense; there are additional costs like transportation, tips, meals, and more. Similarly, in Bubble, an action like modifying a database doesn't just consume its base workload units. You also need to account for the actions required to locate the data and any subsequent updates or queries, each adding to the total workload units consumed.</p>
<h4 id="heading-key-factors-influencing-workload-units"><strong>Key Factors Influencing Workload Units</strong></h4>
<ul>
<li><p><strong>Database Searches</strong>: The complexity and volume of your database searches significantly impact workload units. Optimizing search constraints can lead to more efficient searches and lower consumption.</p>
</li>
<li><p><strong>Data Transfer</strong>: The amount of data sent to the client side, governed by privacy rules, also affects workload units. Less data transfer means fewer units consumed.</p>
</li>
<li><p><strong>Page Loads</strong>: The process of loading a page, including fetching JavaScript, data, and executing page load events, consumes workload units. Optimizing what loads on a page can lead to savings.</p>
</li>
<li><p><strong>Actions and Workflows</strong>: Server-side actions and workflows consume workload units, while client-side actions do not. Prioritizing optimization for frequently called actions can reduce overall consumption.</p>
</li>
</ul>
<h3 id="heading-strategies-for-reducing-workload-units"><strong>Strategies for Reducing Workload Units</strong></h3>
<ol>
<li><p><strong>Optimize Database Searches</strong>: Use precise search constraints to minimize unnecessary data processing.</p>
</li>
<li><p><strong>Manage Data Transfer Efficiently</strong>: Implement strict privacy rules to limit the data transferred to the client side.</p>
</li>
<li><p><strong>Optimize Page Loads</strong>: Avoid unnecessary loading of elements and data on page load events to reduce workload units.</p>
</li>
<li><p><strong>Focus on Frequent Actions</strong>: Identify and optimize the actions and workflows that are called frequently and consume the most workload units.</p>
</li>
<li><p><strong>Use Back-end Workflows Wisely</strong>: Choose between parallel and sequential execution based on your needs to avoid excessive workload unit consumption.</p>
</li>
<li><p><strong>Monitor Workload Units</strong>: Regularly review your app's workload unit consumption through Bubble's logs and metrics to identify areas for improvement.</p>
</li>
</ol>
<h3 id="heading-conclusion"><strong>Conclusion</strong></h3>
<p>Managing workload units in Bubble is about understanding the factors that contribute to their consumption and implementing strategies to optimize and reduce this consumption.</p>
<p>Remember, optimizing workload units should not compromise the functionality or security of your app. It's about finding the right balance between performance and resource consumption.</p>
<p>For more detailed insights into managing workload units in Bubble, watch the full video <a target="_blank" href="https://www.youtube.com/watch?v=1iblvdntwHU"><strong>here</strong></a>.<br />Follow me on <a target="_blank" href="https://twitter.com/NocodeTalks">Twitter</a>.</p>
]]></content:encoded></item><item><title><![CDATA[Easy Guide to Referencing Bubble Elements Within Bubble Plugin]]></title><description><![CDATA[There are instances when you may need to access an element created within the Bubble editor. For example, in a plugin, you might want to return the number of characters a user types into an input element.
Follow these steps:
Step 1:
Enable the "Expos...]]></description><link>https://blog.nocodetalks.co/easy-guide-to-referencing-bubble-elements-within-bubble-plugin</link><guid isPermaLink="true">https://blog.nocodetalks.co/easy-guide-to-referencing-bubble-elements-within-bubble-plugin</guid><category><![CDATA[bubble.io]]></category><category><![CDATA[HTML5]]></category><category><![CDATA[plugins]]></category><dc:creator><![CDATA[Ankur Khandelwal]]></dc:creator><pubDate>Wed, 15 Nov 2023 04:30:13 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1697085756024/6358e8b8-1191-47bd-80e3-3c09b4580718.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>There are instances when you may need to access an element created within the Bubble editor. For example, in a plugin, you might want to return the number of characters a user types into an input element.</p>
<p>Follow these steps:</p>
<p><strong>Step 1:</strong></p>
<p>Enable the "Expose the option to add an ID to HTML elements" by navigating to Settings &gt; General, and scrolling to the bottom of the page.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697023937828/8d725d12-e84c-4d05-91bd-9b0e5e222216.png" alt class="image--center mx-auto" /></p>
<p><strong>Step 2:</strong></p>
<p>Locate the element for which you want to assign a custom ID, and enter the desired ID in the "ID Attribute" field.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697024665091/46e33055-bfb6-4457-9ae1-d7dd28e24e4a.png" alt class="image--center mx-auto" /></p>
<p><strong>Step 3:</strong></p>
<p>Create the plugin using "text" as the input and pass this ID to the plugin's input.</p>
<p><strong>Step 4:</strong></p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> element = <span class="hljs-built_in">document</span>.getElementById(properties.html_id);
  <span class="hljs-built_in">console</span>.log(element);
</code></pre>
<p>That's it..</p>
<hr />
<p>That's all for this blog. Subscribe for more future updates. Thank you!</p>
<p>Follow me on <a target="_blank" href="https://twitter.com/NocodeTalks">Twitter</a>.</p>
<p><strong>Checkout My Bubble Plugin Course</strong> - Use coupon code "THEBUBBLEGROUP" at checkout for 10% discount.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://nocodetalks.co/bubbleplugin">https://nocodetalks.co/bubbleplugin</a></div>
]]></content:encoded></item><item><title><![CDATA[Call API inside the action in Bubble Plugin]]></title><description><![CDATA[There are times when you need to call the API within the action section instead of the API section, but how do you do it?
Let me demonstrate with an example.
I will call this GET API: https://api.thecatapi.com/v1/images/search
GET API Example -Copy a...]]></description><link>https://blog.nocodetalks.co/call-api-inside-the-action-in-bubble-plugin</link><guid isPermaLink="true">https://blog.nocodetalks.co/call-api-inside-the-action-in-bubble-plugin</guid><category><![CDATA[APIs]]></category><category><![CDATA[Actions]]></category><category><![CDATA[bubble.io]]></category><category><![CDATA[plugins]]></category><dc:creator><![CDATA[Ankur Khandelwal]]></dc:creator><pubDate>Tue, 14 Nov 2023 04:30:09 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1697085610263/5a016151-77b0-4aa0-a781-383c61dfedec.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>There are times when you need to call the API within the action section instead of the API section, but how do you do it?</p>
<p>Let me demonstrate with an example.</p>
<p>I will call this GET API: https://api.thecatapi.com/v1/images/search</p>
<p><strong>GET API Example -</strong><br />Copy and paste this code into the action function.</p>
<pre><code class="lang-javascript">
    <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">'https://api.thecatapi.com/v1/images/search'</span>)
    <span class="hljs-keyword">const</span> body = <span class="hljs-keyword">await</span> response.json()
    <span class="hljs-keyword">const</span> cat_image = body[<span class="hljs-number">0</span>].url

    <span class="hljs-keyword">return</span> {
        <span class="hljs-string">"cat_image"</span>:cat_image 
    }
</code></pre>
<p><strong>POST API Example-</strong></p>
<pre><code class="lang-javascript"> <span class="hljs-keyword">const</span> url = <span class="hljs-string">'https://dummy.restapiexample.com/api/v1/create'</span>;
<span class="hljs-comment">//body request</span>
  <span class="hljs-keyword">const</span> data = {
    <span class="hljs-attr">name</span>: <span class="hljs-string">'value1'</span>,
    <span class="hljs-attr">salary</span>: <span class="hljs-string">'value2'</span>,
    <span class="hljs-attr">age</span>: <span class="hljs-string">'value2'</span>
  };    


  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(url, {
      <span class="hljs-attr">method</span>: <span class="hljs-string">'POST'</span>,
      <span class="hljs-attr">headers</span>: {
        <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'application/json'</span>
      },
      <span class="hljs-attr">body</span>: <span class="hljs-built_in">JSON</span>.stringify(data)
    });

    <span class="hljs-keyword">const</span> responseData = <span class="hljs-keyword">await</span> response.json();
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Success:'</span>, responseData);
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'Error:'</span>, error);
  }
</code></pre>
<hr />
<p>That's all for this blog. Subscribe for more future updates. Thank you!</p>
<p>Follow me on <a target="_blank" href="https://twitter.com/NocodeTalks">Twitter</a>.</p>
<p><strong>Checkout My Bubble Plugin Course</strong> - Use coupon code "THEBUBBLEGROUP" at checkout for 10% discount.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://nocodetalks.co/bubbleplugin">https://nocodetalks.co/bubbleplugin</a></div>
]]></content:encoded></item><item><title><![CDATA[Call API inside the element in Bubble Plugin]]></title><description><![CDATA[There are times when you need to call the API within the element section instead of the API section, but how do you do it?
Let me demonstrate with an example.
I will call this GET API: https://dummy.restapiexample.com/api/v1/employees
We will be usin...]]></description><link>https://blog.nocodetalks.co/call-api-inside-the-element-in-bubble-plugin</link><guid isPermaLink="true">https://blog.nocodetalks.co/call-api-inside-the-element-in-bubble-plugin</guid><category><![CDATA[bubble.io]]></category><category><![CDATA[plugins]]></category><category><![CDATA[APIs]]></category><category><![CDATA[elements]]></category><dc:creator><![CDATA[Ankur Khandelwal]]></dc:creator><pubDate>Mon, 13 Nov 2023 04:30:12 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1697085696524/fd17aeda-4c6d-41ec-be8c-1f077bcfce8c.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>There are times when you need to call the API within the element section instead of the API section, but how do you do it?</p>
<p>Let me demonstrate with an example.</p>
<p>I will call this GET API: https://dummy.restapiexample.com/api/v1/employees</p>
<p>We will be using jQuery for this purpose.</p>
<pre><code class="lang-javascript"> $.getJSON(<span class="hljs-string">'https://dummy.restapiexample.com/api/v1/employees'</span>)
    .done(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">json_data</span>) </span>{
         <span class="hljs-comment">//success </span>
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"data is "</span> , json_data);
    })
    .fail(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">jqXHR, textStatus, errorThrown</span>) </span>{
        <span class="hljs-comment">//come here if there is any error while calling the api</span>
        <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Error: "</span> + textStatus + <span class="hljs-string">", "</span> + errorThrown);
    });
</code></pre>
<p>POST API Example-</p>
<pre><code class="lang-javascript">$.post(<span class="hljs-string">'https://dummy.restapiexample.com/create'</span>, {<span class="hljs-attr">name</span>:<span class="hljs-string">'test'</span>,<span class="hljs-attr">salary</span>:<span class="hljs-string">'123'</span>,<span class="hljs-attr">age</span>:<span class="hljs-string">'23'</span>}    )
  .done(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">response</span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Success:'</span>, response);
  })
  .fail(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">jqXHR, textStatus, errorThrown</span>) </span>{
    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'Error:'</span>, textStatus, errorThrown);
  });
</code></pre>
<hr />
<p>That's all for this blog. Subscribe for more future updates. Thank you!</p>
<p>Follow me on <a target="_blank" href="https://twitter.com/NocodeTalks">Twitter</a>.</p>
<p><strong>Checkout My Bubble Plugin Course</strong> - Use coupon code "THEBUBBLEGROUP" at checkout for 10% discount.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://nocodetalks.co/bubbleplugin">https://nocodetalks.co/bubbleplugin</a></div>
]]></content:encoded></item><item><title><![CDATA[Handling Lists within Bubble Plugin Editor]]></title><description><![CDATA[If you have ever attempted to work with the custom object list in the Bubble plugin editor, you know it has become a nightmare to manage. Not anymore.

So let's assume you are building the plugin that consists of client-side element and you are passi...]]></description><link>https://blog.nocodetalks.co/handling-lists-within-bubble-plugin-editor</link><guid isPermaLink="true">https://blog.nocodetalks.co/handling-lists-within-bubble-plugin-editor</guid><category><![CDATA[bubble.io]]></category><category><![CDATA[plugins]]></category><category><![CDATA[Lists]]></category><dc:creator><![CDATA[Ankur Khandelwal]]></dc:creator><pubDate>Thu, 09 Nov 2023 04:30:12 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1697085529986/abc680ce-8bbf-4a75-985f-818eb546c89d.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you have ever attempted to work with the custom object list in the Bubble plugin editor, you know it has become a nightmare to manage. Not anymore.</p>
<hr />
<p>So let's assume you are building the plugin that consists of client-side element and you are passing "anything with list" as the input.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697017876131/3ee35a94-782f-41e4-8630-75fe3ce2e06b.png" alt class="image--center mx-auto" /></p>
<p>Now, experiment with the input data in the plugin editor.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> length_data = properties.anything_data.length(); <span class="hljs-comment">//lenght of input list</span>

    <span class="hljs-keyword">var</span> properties_data = properties.anything_data.get(<span class="hljs-number">0</span>, length_data); <span class="hljs-comment">//input data list</span>

    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Length"</span>, length_data);

    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"All data"</span>, properties_data);

    <span class="hljs-comment">//looping over list</span>
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> idx=<span class="hljs-number">0</span>; idx &lt; length_data; idx++){
            <span class="hljs-comment">//get the one item at time</span>
                <span class="hljs-keyword">let</span> list_item = properties_data[idx];
             <span class="hljs-comment">//this will list all the column of the given data type as the json array              </span>
               <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"list properties"</span>, list_item.listProperties());

              <span class="hljs-keyword">for</span>(<span class="hljs-keyword">let</span> prop=<span class="hljs-number">0</span>; prop&lt;list_item.listProperties().length; prop++){

                 <span class="hljs-comment">//column name along with type , for ex- coulumn_name_type     </span>
                 <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"key:"</span>, list_item.listProperties()[prop]);  <span class="hljs-comment">//event_name_text - event_name is the column name and text is the type</span>
                 <span class="hljs-comment">//its value</span>
                 <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"value:"</span>, list_item.get(list_item.listProperties()[prop]));

             }

        }
</code></pre>
<hr />
<p>That's all for this blog. Subscribe for more future updates. Thank you!</p>
<p>Follow me on <a target="_blank" href="https://twitter.com/NocodeTalks">Twitter</a>.</p>
<p><strong>Checkout My Bubble Plugin Course</strong> - Use coupon code "THEBUBBLEGROUP" at checkout for 10% discount.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://nocodetalks.co/bubbleplugin">https://nocodetalks.co/bubbleplugin</a></div>
]]></content:encoded></item><item><title><![CDATA[Get Premium Bubble Plugins for Free]]></title><description><![CDATA[If you wish to obtain a paid plugin for free or test any paid plugin before purchasing, you should create an agency account and subscribe to any paid plugin at no cost (please note that lifetime purchases are not available).

That's all for this blog...]]></description><link>https://blog.nocodetalks.co/get-premium-bubble-plugins-for-free</link><guid isPermaLink="true">https://blog.nocodetalks.co/get-premium-bubble-plugins-for-free</guid><category><![CDATA[bubble.io]]></category><category><![CDATA[plugins]]></category><category><![CDATA[free]]></category><category><![CDATA[Paid]]></category><category><![CDATA[premium]]></category><dc:creator><![CDATA[Ankur Khandelwal]]></dc:creator><pubDate>Wed, 08 Nov 2023 04:30:12 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1697085417025/9b797ca1-5dae-48d1-b9c5-ecd55ca6c373.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you wish to obtain a paid plugin for free or test any paid plugin before purchasing, you should create an <a target="_blank" href="https://bubble.io/agency-plan?ref=pricing">agency account</a> and subscribe to any paid plugin at no cost (please note that lifetime purchases are not available).</p>
<hr />
<p>That's all for this blog. Subscribe for more future updates. Thank you!</p>
<p>Follow me on <a target="_blank" href="https://twitter.com/NocodeTalks">Twitter</a>.</p>
<p><strong>Checkout My Bubble Plugin Course</strong> - Use coupon code "THEBUBBLEGROUP" at checkout for 10% discount.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://nocodetalks.co/bubbleplugin">https://nocodetalks.co/bubbleplugin</a></div>
]]></content:encoded></item><item><title><![CDATA[Setting up API Calls in Bubble Plugin Editor: A Step-by-Step Guide]]></title><description><![CDATA[You can set up the API calls in the plugin editor just as you did in the API connector.
Go to the "API Calls" section of the plugin editor.

To start the API calls, click on "Add an API connection".

Now, simply provide the name of the API you are se...]]></description><link>https://blog.nocodetalks.co/setting-up-api-calls-in-bubble-plugin-editor-a-step-by-step-guide</link><guid isPermaLink="true">https://blog.nocodetalks.co/setting-up-api-calls-in-bubble-plugin-editor-a-step-by-step-guide</guid><category><![CDATA[bubble.io]]></category><category><![CDATA[plugins]]></category><category><![CDATA[APIs]]></category><category><![CDATA[plugin]]></category><dc:creator><![CDATA[Ankur Khandelwal]]></dc:creator><pubDate>Tue, 07 Nov 2023 04:30:10 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1697085328203/88b041d2-cd23-4a20-a542-d1a9e3bfa8b1.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>You can set up the API calls in the plugin editor just as you did in the API connector.</p>
<p>Go to the "API Calls" section of the plugin editor.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697015026592/66489892-3135-4d64-957c-bb3f3ff1b1fc.png" alt class="image--center mx-auto" /></p>
<p>To start the API calls, click on <strong>"Add an API connection"</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697015059838/0f3cc515-27df-4b31-8775-f3904fd635e3.png" alt class="image--center mx-auto" /></p>
<p>Now, simply provide the name of the API you are setting up. For example, we will set up the "Stripe" API calls.</p>
<p>Configure the authentication required for your API calls. The type of authentication you select here will determine the corresponding fields exposed in the Bubble plugin.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697015503314/a912d872-a1b6-472b-8e68-80cce7f71181.png" alt class="image--center mx-auto" /></p>
<p>Now, for example, if we want to set up this API for API calls-</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697015564037/481266dd-b707-40e5-8626-97c4bf0a16ec.png" alt class="image--center mx-auto" /></p>
<p>Click on "Initialize Call" to set up the API calls.</p>
<p>That's how you set up the API calls in the Bubble plugin editor.</p>
<hr />
<p>That's all for this blog. Subscribe for more future updates. Thank you!</p>
<p>Follow me on <a target="_blank" href="https://twitter.com/NocodeTalks">Twitter</a>.</p>
<p><strong>Checkout My Bubble Plugin Course</strong> - Use coupon code "THEBUBBLEGROUP" at checkout for 10% discount.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://nocodetalks.co/bubbleplugin">https://nocodetalks.co/bubbleplugin</a></div>
]]></content:encoded></item><item><title><![CDATA[Work with Bubble database data in Plugin editor]]></title><description><![CDATA[If you want your user to pass the Bubble database data type to the Bubble plugin editor, how would you accomplish this?
Follow these steps:
Step 1:
Define the first field input as the "App Type" and the second as a dynamic value with the type of "fir...]]></description><link>https://blog.nocodetalks.co/work-with-bubble-database-data-in-plugin-editor</link><guid isPermaLink="true">https://blog.nocodetalks.co/work-with-bubble-database-data-in-plugin-editor</guid><category><![CDATA[bubble.io]]></category><category><![CDATA[Bubble Developers]]></category><category><![CDATA[database]]></category><category><![CDATA[data types]]></category><dc:creator><![CDATA[Ankur Khandelwal]]></dc:creator><pubDate>Mon, 06 Nov 2023 04:30:09 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1697085022034/11a0351a-9cb3-43dd-b0db-a0e5d603b5c7.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you want your user to pass the Bubble database data type to the Bubble plugin editor, how would you accomplish this?</p>
<p>Follow these steps:</p>
<p><strong>Step 1:</strong></p>
<p>Define the first field input as the "App Type" and the second as a dynamic value with the type of "first input type."</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697013542847/0d275bf5-0377-4d23-bd87-72a4473a65d7.png" alt class="image--center mx-auto" /></p>
<p>Drag the element to the editor, you will see two inputs:</p>
<p>- In the first input, provide the Input type.</p>
<p>- In the second input, supply the data.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697013600997/40f12655-473e-4ad7-91b9-21ad844065a4.png" alt class="image--center mx-auto" /></p>
<p><strong>Step 2:</strong></p>
<p>Now, experiment with the input data in the plugin editor.</p>
<pre><code class="lang-javascript">     <span class="hljs-comment">//compute the length of the list </span>
    <span class="hljs-keyword">let</span> list_length = properties.input_data.length()
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Length is "</span>, list_length);
    <span class="hljs-comment">//get the input data list</span>
    <span class="hljs-keyword">var</span> list_data =  properties.input_data.get(<span class="hljs-number">0</span>, list_length);
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"List data"</span> , list_data);

    <span class="hljs-comment">//loop over input list</span>
     <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> idx=<span class="hljs-number">0</span>; idx &lt; list_length; idx++){
            <span class="hljs-comment">//get the one item at time</span>
                <span class="hljs-keyword">let</span> list_item = list_data[idx];
             <span class="hljs-comment">//this will list all the column of the given data type as the json array              </span>
               <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"list properties"</span>, list_item.listProperties());

              <span class="hljs-keyword">for</span>(<span class="hljs-keyword">let</span> prop=<span class="hljs-number">0</span>; prop&lt;list_item.listProperties().length; prop++){

                 <span class="hljs-comment">//column name along with type , for ex- coulumn_name_type     </span>
                 <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"key:"</span>, list_item.listProperties()[prop]);  <span class="hljs-comment">//event_name_text - event_name is the column name and text is the type</span>
                 <span class="hljs-comment">//its value</span>
                 <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"value:"</span>, list_item.get(list_item.listProperties()[prop]));

             }

        }
</code></pre>
<hr />
<p>That's all for this blog. Subscribe for more future updates. Thank you!</p>
<p>Follow me on <a target="_blank" href="https://twitter.com/NocodeTalks">Twitter</a>.</p>
<p><strong>Checkout My Bubble Plugin Course</strong> - Use coupon code "THEBUBBLEGROUP" at checkout for 10% discount.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://nocodetalks.co/bubbleplugin">https://nocodetalks.co/bubbleplugin</a></div>
]]></content:encoded></item><item><title><![CDATA[Bubble Plugin API Calls: Exploring Diverse Parameter Types]]></title><description><![CDATA[If you are developing a plugin using an API, you may have noticed that there are three types of parameters - private, hidden, and secret, which differ from the private and public parameters found in an API connector.

What's the difference between th...]]></description><link>https://blog.nocodetalks.co/bubble-plugin-api-calls-exploring-diverse-parameter-types</link><guid isPermaLink="true">https://blog.nocodetalks.co/bubble-plugin-api-calls-exploring-diverse-parameter-types</guid><category><![CDATA[bubble.io]]></category><category><![CDATA[plugins]]></category><category><![CDATA[APIs]]></category><category><![CDATA[Parameters]]></category><dc:creator><![CDATA[Ankur Khandelwal]]></dc:creator><pubDate>Thu, 02 Nov 2023 04:30:12 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1697084897236/a82d4e7d-73d1-4c82-bee4-5ff13ed8810e.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you are developing a plugin using an API, you may have noticed that there are three types of parameters - private, hidden, and secret, which differ from the private and public parameters found in an API connector.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697005623501/884d48e6-d499-45ba-95dc-567315ca4a67.png" alt class="image--center mx-auto" /></p>
<p>What's the difference between them?</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td></td><td>Public</td><td>Hidden</td><td>Secret</td></tr>
</thead>
<tbody>
<tr>
<td>End user can change the value?</td><td>yes</td><td>no</td><td>no</td></tr>
<tr>
<td>Who can see the value</td><td>everyone</td><td>can see via the inspect element</td><td>no</td></tr>
</tbody>
</table>
</div><p><strong>If you set the parameter type to public</strong>-</p>
<p>Anyone with access to the page can view and modify the value, making the parameter value public.</p>
<p><strong>If you set the parameter type to hidden</strong>-</p>
<p>The plugin installer cannot change the value, but everyone can view its value using the inspect element feature.</p>
<p><strong>If you set the parameter type to secret-</strong></p>
<p>No one can see the value, and they cannot change it either.</p>
<hr />
<p>That's all for this blog. Subscribe for more future updates. Thank you!</p>
<p>Follow me on <a target="_blank" href="https://twitter.com/NocodeTalks">Twitter</a>.</p>
<p><strong>Checkout My Bubble Plugin Course</strong> - Use coupon code "THEBUBBLEGROUP" at checkout for 10% discount.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://nocodetalks.co/bubbleplugin">https://nocodetalks.co/bubbleplugin</a></div>
]]></content:encoded></item><item><title><![CDATA[Adding Preview to Your Bubble Plugin Element: A Simple Guide]]></title><description><![CDATA[While constructing the Bubble plugin, you discovered that when you drag plugin element to the UI editor, it displays "No plugin preview available."
How can this issue be resolved?

You can incorporate any type of UI based on your element's functional...]]></description><link>https://blog.nocodetalks.co/adding-preview-to-your-bubble-plugin-element-a-simple-guide</link><guid isPermaLink="true">https://blog.nocodetalks.co/adding-preview-to-your-bubble-plugin-element-a-simple-guide</guid><category><![CDATA[bubble.io]]></category><category><![CDATA[plugins]]></category><category><![CDATA[elements]]></category><category><![CDATA[preview]]></category><dc:creator><![CDATA[Ankur Khandelwal]]></dc:creator><pubDate>Wed, 01 Nov 2023 04:30:12 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1697084617867/c102c81b-c59f-46f3-b268-a576b7d2214e.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>While constructing the Bubble plugin, you discovered that when you drag plugin element to the UI editor, it displays "No plugin preview available."</p>
<p>How can this issue be resolved?</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697004804595/1fba7ec8-1679-462e-82aa-70794ed8bcbd.png" alt class="image--center mx-auto" /></p>
<p>You can incorporate any type of UI based on your element's functionality. However, it is common for people to use a logo in this situation. In this article, I will demonstrate how to add a logo.</p>
<pre><code class="lang-css">$(<span class="hljs-selector-tag">instance</span><span class="hljs-selector-class">.canvas</span>)<span class="hljs-selector-class">.append</span>(`&lt;<span class="hljs-selector-tag">div</span> <span class="hljs-selector-tag">style</span>="<span class="hljs-selector-tag">background-color</span>: <span class="hljs-selector-id">#E7E9EB</span>;"&gt;&lt;<span class="hljs-selector-tag">img</span> <span class="hljs-selector-tag">src</span>="<span class="hljs-selector-tag">logo_image_url</span><span class="hljs-selector-class">.png</span>" <span class="hljs-selector-tag">style</span>="<span class="hljs-selector-tag">width</span>: 100%; <span class="hljs-selector-tag">height</span>: 100%;"&gt;&lt;/<span class="hljs-selector-tag">div</span>&gt;`)
</code></pre>
<p>You need to copy and paste this code snippet into the preview function.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697005161486/1d1ecb70-9486-4665-9d9a-d285af1a8a05.png" alt class="image--center mx-auto" /></p>
<hr />
<p>That's all for this blog. Subscribe for more future updates. Thank you!</p>
<p>Follow me on <a target="_blank" href="https://twitter.com/NocodeTalks">Twitter</a>.</p>
<p><strong>Checkout My Bubble Plugin Course</strong> - Use coupon code "THEBUBBLEGROUP" at checkout for 10% discount.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://nocodetalks.co/bubbleplugin">https://nocodetalks.co/bubbleplugin</a></div>
]]></content:encoded></item><item><title><![CDATA[How to pass data across function in Bubble plugin?]]></title><description><![CDATA[There are times when you need to pass data between different functions while building a client-side plugin in Bubble. However, there is no native method to accomplish this. One approach is to expose the data and request that user send it as input. Th...]]></description><link>https://blog.nocodetalks.co/how-to-pass-data-across-function-in-bubble-plugin</link><guid isPermaLink="true">https://blog.nocodetalks.co/how-to-pass-data-across-function-in-bubble-plugin</guid><category><![CDATA[bubble.io]]></category><category><![CDATA[plugins]]></category><category><![CDATA[temp]]></category><category><![CDATA[data]]></category><category><![CDATA[Shared Preferences]]></category><dc:creator><![CDATA[Ankur Khandelwal]]></dc:creator><pubDate>Tue, 31 Oct 2023 04:30:10 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1697084533445/822b15ae-87d3-4aea-b516-91a2069920f2.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>There are times when you need to pass data between different functions while building a client-side plugin in Bubble. However, there is no native method to accomplish this. One approach is to expose the data and request that user send it as input. This is arguably the worst solution from the user's perspective.</p>
<p>So, what should you do instead? Define a temporary variable.</p>
<p>It's better to define it within the "initialize" function.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696920288203/e30821e1-1d78-4b13-99de-5da832b4a9a6.png" alt class="image--center mx-auto" /></p>
<pre><code class="lang-javascript"><span class="hljs-comment">//define the variable</span>
instance.data.my_variable= <span class="hljs-string">"this is sample Data"</span>;
</code></pre>
<p>Now you can use the "instance.data.my_variable" anywhere in the client side function.</p>
<hr />
<p>That's all for this blog. Subscribe for more future updates. Thank you!</p>
<p>Follow me on <a target="_blank" href="https://twitter.com/NocodeTalks">Twitter</a>.</p>
<p><strong>Checkout My Bubble Plugin Course</strong> - Use coupon code "THEBUBBLEGROUP" at checkout for 10% discount.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://nocodetalks.co/bubbleplugin">https://nocodetalks.co/bubbleplugin</a></div>
]]></content:encoded></item><item><title><![CDATA[How to load JS Library at client side in Bubble Plugin editor?]]></title><description><![CDATA[If you want to create a client-side plugin that utilizes an existing JavaScript library, you need to load it into the header. To do this in the Bubble plugin editor, follow these steps:
Step 1:
Navigate to the "Element" section of the Bubble editor a...]]></description><link>https://blog.nocodetalks.co/how-to-load-js-library-at-client-side-in-bubble-plugin-editor</link><guid isPermaLink="true">https://blog.nocodetalks.co/how-to-load-js-library-at-client-side-in-bubble-plugin-editor</guid><category><![CDATA[bubble.io]]></category><category><![CDATA[plugins]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[library]]></category><dc:creator><![CDATA[Ankur Khandelwal]]></dc:creator><pubDate>Mon, 30 Oct 2023 04:30:12 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1697084409791/c1536a19-9637-4dbe-9a28-da798e981848.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you want to create a client-side plugin that utilizes an existing JavaScript library, you need to load it into the header. To do this in the Bubble plugin editor, follow these steps:</p>
<p><strong>Step 1:</strong></p>
<p>Navigate to the "Element" section of the Bubble editor and create a new client-side element.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696919277735/92337a71-f348-449a-aa81-928de493f268.png" alt class="image--center mx-auto" /></p>
<p><strong>Step 2:</strong></p>
<p>Scroll down to the "Element Code" section within the element.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696919303639/4bba6bcb-a1fa-4b9c-a762-b174d06f715f.png" alt class="image--center mx-auto" /></p>
<p><strong>Step 3:</strong></p>
<p>Search for the library you wish to import and obtain its CDN URL (refer to this article to find the CDN URL). Then, insert the following code into the "Element Code" section.</p>
<pre><code class="lang-javascript">&lt;script src=<span class="hljs-string">"https://www.WebRTC-Experiment.com/RecordRTC.js"</span>&gt;&lt;/script&gt;
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696919516226/368c0fd9-2e35-4db1-a557-310804fd776d.png" alt class="image--center mx-auto" /></p>
<p>That's it, you have load the library.</p>
<hr />
<p>That's all for this blog. Subscribe for more future updates. Thank you!</p>
<p>Follow me on <a target="_blank" href="https://twitter.com/NocodeTalks">Twitter</a>.</p>
<p><strong>Checkout My Bubble Plugin Course</strong> - Use coupon code "THEBUBBLEGROUP" at checkout for 10% discount.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://nocodetalks.co/bubbleplugin">https://nocodetalks.co/bubbleplugin</a></div>
]]></content:encoded></item><item><title><![CDATA[JavaScript Library CDN: Fast and Efficient Distribution]]></title><description><![CDATA[When you load a library on the client side in the Bubble plugin editor, that library is either hosted externally or on Bubble's server.

For example, if you refer to the image above, the RecordRTC library is hosted on the WebRTC server, but not all l...]]></description><link>https://blog.nocodetalks.co/javascript-library-cdn-fast-and-efficient-distribution</link><guid isPermaLink="true">https://blog.nocodetalks.co/javascript-library-cdn-fast-and-efficient-distribution</guid><category><![CDATA[bubble.io]]></category><category><![CDATA[plugins]]></category><category><![CDATA[CDN]]></category><category><![CDATA[client]]></category><dc:creator><![CDATA[Ankur Khandelwal]]></dc:creator><pubDate>Thu, 26 Oct 2023 04:30:09 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1697084339852/d9f52c3a-66c9-4956-92b6-1c5400ea106a.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>When you load a library on the client side in the Bubble plugin editor, that library is either hosted externally or on Bubble's server.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696918337633/3ed8d7db-c892-400c-b391-8f977ed689e8.png" alt class="image--center mx-auto" /></p>
<p>For example, if you refer to the image above, the RecordRTC library is hosted on the WebRTC server, but not all libraries are hosted on their own servers, especially open-source ones.</p>
<p>However, most of these libraries are hosted on CDNs (Content Delivery Networks). CDNs are file-hosting services that provide multiple versions of common libraries. They typically offer high-performance and location-cached files, ensuring that your users receive the files from geographically close locations, regardless of where they are.</p>
<p>Therefore, if you need any library, it is better to use these CDNs rather than uploading it to your own Bubble server.</p>
<p>Here are some prominent CDNs for JavaScript libraries:</p>
<p>- <a target="_blank" href="https://cdnjs.com/">CDNJS</a> - <a target="_blank" href="https://www.jsdelivr.com/">JSDelivr</a> - <a target="_blank" href="https://www.unpkg.com/">Unpkg</a></p>
<p>Visit these CDNs and search for the library you need. You will find the URL for that library, which you can use in the plugin editor to load the library on the client side.</p>
<hr />
<p>That's all for this blog. Subscribe for more future updates. Thank you!</p>
<p>Follow me on <a target="_blank" href="https://twitter.com/NocodeTalks">Twitter</a>.</p>
<p><strong>Checkout My Bubble Plugin Course</strong> - Use coupon code "THEBUBBLEGROUP" at checkout for 10% discount.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://nocodetalks.co/bubbleplugin">https://nocodetalks.co/bubbleplugin</a></div>
]]></content:encoded></item><item><title><![CDATA[How to pick correct JS library for Building Bubble plugin?]]></title><description><![CDATA[So you're facing Bubble limitations and planning to build a plugin. However, there's a good chance that someone has already solved the problem and packaged it into a JavaScript library. It's always better to use an existing library rather than buildi...]]></description><link>https://blog.nocodetalks.co/how-to-pick-correct-js-library-for-building-bubble-plugin</link><guid isPermaLink="true">https://blog.nocodetalks.co/how-to-pick-correct-js-library-for-building-bubble-plugin</guid><category><![CDATA[bubble.io]]></category><category><![CDATA[plugins]]></category><category><![CDATA[js]]></category><category><![CDATA[library]]></category><dc:creator><![CDATA[Ankur Khandelwal]]></dc:creator><pubDate>Wed, 25 Oct 2023 04:30:12 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1697084260379/0f02d7c1-a697-4afc-808a-85d1a22858a9.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>So you're facing Bubble limitations and planning to build a plugin. However, there's a good chance that someone has already solved the problem and packaged it into a JavaScript library. It's always better to use an existing library rather than building one from scratch.</p>
<p>Let's say you want to build an audio recorder plugin; you might search for it on Google but end up finding numerous libraries and struggle to decide which one to choose.</p>
<p>Let me help you with this process:</p>
<p><strong>Step 1:</strong></p>
<p>List all the features you want in this plugin.</p>
<p>Since we want to build an "Audio Recorder" plugin, let's write down its sub-features:</p>
<p>- Start audio recording - Stop audio recording - Pause/resume recording - Option to upload recording to the server - Stop recording at a pre-defined time</p>
<p><strong>Step 2:</strong></p>
<p>Visit <a target="_blank" href="https://www.npmjs.com/">npm</a> and search for JavaScript libraries using relevant keywords.</p>
<p><strong>Step 3:</strong></p>
<p>Review each library's documentation to determine if it supports the features mentioned in Step 1.</p>
<p><strong>Step 4:</strong></p>
<p>Don't forget to check the issue section on GitHub for each library. See if people are answering questions and if there's a good community of developers. This way, if you encounter issues in the future, there will be people to help you.</p>
<p><strong>Step 5:</strong></p>
<p>Check the size of the library, which is important if you're using it on the client side.</p>
<hr />
<p>That's all for this blog. Subscribe for more future updates. Thank you!</p>
<p>Follow me on <a target="_blank" href="https://twitter.com/NocodeTalks">Twitter</a>.</p>
<p><strong>Checkout My Bubble Plugin Course</strong> - Use coupon code "THEBUBBLEGROUP" at checkout for 10% discount.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://nocodetalks.co/bubbleplugin">https://nocodetalks.co/bubbleplugin</a></div>
]]></content:encoded></item><item><title><![CDATA[How to upload Base64 data in client side Bubble plugin?]]></title><description><![CDATA[Converting various file types, such as images and PDFs, into base64 strings is an excellent method for storing them in a database. Bubble's File API only permits base64 data uploads, disallowing direct uploads of PDFs and images.
Use the following co...]]></description><link>https://blog.nocodetalks.co/how-to-upload-base64-data-in-client-side-bubble-plugin</link><guid isPermaLink="true">https://blog.nocodetalks.co/how-to-upload-base64-data-in-client-side-bubble-plugin</guid><category><![CDATA[bubble.io]]></category><category><![CDATA[plugins]]></category><category><![CDATA[Base64]]></category><category><![CDATA[client]]></category><dc:creator><![CDATA[Ankur Khandelwal]]></dc:creator><pubDate>Tue, 24 Oct 2023 04:30:09 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1697084181707/483b4c01-098f-4bf6-8dad-0bf73b129881.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Converting various file types, such as images and PDFs, into base64 strings is an excellent method for storing them in a database. Bubble's File API only permits base64 data uploads, disallowing direct uploads of PDFs and images.</p>
<p>Use the following code to upload Base64 data to Bubble File Manager.</p>
<pre><code class="lang-javascript">context.uploadContent(properties.file_name,base64_data, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">err, url</span>)</span>{

                        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"URL"</span>, <span class="hljs-string">"https:"</span>+url);

                    });
</code></pre>
<p>Do read <a target="_blank" href="https://forum.bubble.io/t/important-information-about-context-uploadcontent/198088">this post</a> on how to format base64 data before sending it.</p>
<hr />
<p>That's all for this blog. Subscribe for more future updates. Thank you!</p>
<p>Follow me on <a target="_blank" href="https://twitter.com/NocodeTalks">Twitter</a>.</p>
<p><strong>Checkout My Bubble Plugin Course</strong> - Use coupon code "THEBUBBLEGROUP" at checkout for 10% discount.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://nocodetalks.co/bubbleplugin">https://nocodetalks.co/bubbleplugin</a></div>
]]></content:encoded></item><item><title><![CDATA[How to upload Base64 data in server side Bubble plugin action?]]></title><description><![CDATA[Converting various file types, such as images and PDFs, into base64 strings is an excellent method for storing them in a database. Bubble's File API only permits base64 data uploads, disallowing direct uploads of PDFs and images.
By default, Bubble e...]]></description><link>https://blog.nocodetalks.co/how-to-upload-base64-data-in-server-side-bubble-plugin-action</link><guid isPermaLink="true">https://blog.nocodetalks.co/how-to-upload-base64-data-in-server-side-bubble-plugin-action</guid><category><![CDATA[Base64]]></category><category><![CDATA[server]]></category><category><![CDATA[bubble]]></category><category><![CDATA[bubble.io]]></category><dc:creator><![CDATA[Ankur Khandelwal]]></dc:creator><pubDate>Mon, 23 Oct 2023 04:30:12 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1697084122841/7fdedc94-13fa-426f-a84e-ee3733354be6.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Converting various file types, such as images and PDFs, into base64 strings is an excellent method for storing them in a database. Bubble's File API only permits base64 data uploads, disallowing direct uploads of PDFs and images.</p>
<p>By default, Bubble exposes the "fileupload" API for uploading base64 data.</p>
<p>Use the following code to upload Base64 data to Bubble File Manager.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> payload = {
        <span class="hljs-attr">name</span>: properties.file_name,
        <span class="hljs-attr">contents</span>: base64_data
    };


<span class="hljs-keyword">var</span> options = {
    <span class="hljs-attr">uri</span>: properties.website_home_url + <span class="hljs-string">"fileupload"</span>,
    <span class="hljs-attr">method</span>: <span class="hljs-string">"POST"</span>,
    <span class="hljs-attr">json</span>: payload
};

<span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> context.v3.request(options);
</code></pre>
<hr />
<p>That's all for this blog. Subscribe for more future updates. Thank you!</p>
<p>Follow me on <a target="_blank" href="https://twitter.com/NocodeTalks">Twitter</a>.</p>
<p><strong>Checkout My Bubble Plugin Course</strong> - Use coupon code "THEBUBBLEGROUP" at checkout for 10% discount.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://nocodetalks.co/bubbleplugin">https://nocodetalks.co/bubbleplugin</a></div>
]]></content:encoded></item><item><title><![CDATA[How to return File type data in element in Bubble plugin?]]></title><description><![CDATA[While making the "File-uploader" or any file-related plugin, you realize it's better to use the "File" data type instead of showing the "file-url" as text. Using the "File" data type instead of "file-url" has many advantages. For example, you can put...]]></description><link>https://blog.nocodetalks.co/how-to-return-file-type-data-in-element-in-bubble-plugin</link><guid isPermaLink="true">https://blog.nocodetalks.co/how-to-return-file-type-data-in-element-in-bubble-plugin</guid><category><![CDATA[bubble.io]]></category><category><![CDATA[plugins]]></category><category><![CDATA[files]]></category><category><![CDATA[data types]]></category><dc:creator><![CDATA[Ankur Khandelwal]]></dc:creator><pubDate>Thu, 19 Oct 2023 04:30:10 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1697083573316/ea735da6-0754-4a59-9e1e-b8cc47f55fd3.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>While making the "File-uploader" or any file-related plugin, you realize it's better to use the "File" data type instead of showing the "file-url" as text. Using the "File" data type instead of "file-url" has many advantages. For example, you can put the "File-name" and "File-url" in the same variable instead of making two separate variables. You can also directly save the "File" type data into Bubble DB.</p>
<p>But the real question is how to do it -</p>
<p>Follow these steps-</p>
<p><strong>Step 1:</strong></p>
<p>Create the variable type "File" as the exposed state-</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696912324463/97824cb4-d9e8-4529-817f-a38a5c5b1824.png" alt class="image--center mx-auto" /></p>
<p><strong>Step 2:</strong></p>
<p>Create a variable to hold the file URL (remember to add the "https" prefix if it's not already included) and then expose the variable.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> file_url = <span class="hljs-string">"https"</span>+url_without_http; 
instance.publishState(<span class="hljs-string">"uploaded_file"</span>,file_url);
</code></pre>
<p>It will automatically expose the file-name too.</p>
<hr />
<p>That's all for this blog. Subscribe for more future updates. Thank you!</p>
<p>Follow me on <a target="_blank" href="https://twitter.com/NocodeTalks">twitter</a>.</p>
<p><strong>Checkout My Bubble Plugin Course</strong> - Use coupon code "THEBUBBLEGROUP" at checkout for 10% discount.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://nocodetalks.co/bubbleplugin">https://nocodetalks.co/bubbleplugin</a></div>
]]></content:encoded></item></channel></rss>