diff --git a/.github/workflows/build-errors-check.yml b/.github/workflows/build-errors-check.yml index b936fb43f..aa3713541 100644 --- a/.github/workflows/build-errors-check.yml +++ b/.github/workflows/build-errors-check.yml @@ -15,12 +15,16 @@ jobs: fetch-depth: 0 - name: Install Dependencies - run: npm install + run: npm ci + + - name: Typecheck + run: npm run typecheck - name: Build run: npm run build + - name: Audit SEO and agent artifacts + run: npm run audit:seo-agent:built - - - + - name: Evaluate agent retrieval + run: npm run eval:agent-retrieval diff --git a/.github/workflows/content-freshness.yml b/.github/workflows/content-freshness.yml new file mode 100644 index 000000000..e60fbc8fc --- /dev/null +++ b/.github/workflows/content-freshness.yml @@ -0,0 +1,37 @@ +name: Documentation Freshness SLA + +on: + workflow_dispatch: + schedule: + - cron: '17 8 * * 1' + +jobs: + freshness-audit: + runs-on: ubuntu-latest + steps: + - name: Checkout full history + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Install dependencies + run: npm ci + + - name: Build canonical artifacts + run: npm run build + + - name: Enforce freshness SLA + id: freshness + continue-on-error: true + run: npm run audit:seo-agent:strict + + - name: Upload freshness report + if: always() + uses: actions/upload-artifact@v4 + with: + name: documentation-freshness-report + path: reports/seo-agent-audit.* + + - name: Fail when pages exceed SLA + if: steps.freshness.outcome == 'failure' + run: exit 1 diff --git a/.gitignore b/.gitignore index b2d6de306..5d440f894 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ # Production /build +/reports # Generated files .docusaurus diff --git a/CONTENT_QUALITY.md b/CONTENT_QUALITY.md new file mode 100644 index 000000000..efe7c05eb --- /dev/null +++ b/CONTENT_QUALITY.md @@ -0,0 +1,99 @@ +# Documentation search and agent quality standard + +This repository treats human search, web search, and AI-agent retrieval as one publishing system. A page is not complete merely because it renders: it must be discoverable, uniquely identifiable, current, accessible, and safe to use as cited answer context. + +## A+ release gates + +An A+ metric is at least 98%. The production build and `npm run audit:seo-agent:built` measure the following gates: + +| Metric | A+ requirement | +| --- | --- | +| Crawl and indexation | Every canonical page is allowed by `robots.txt`, appears once in the sitemap, has an evidence-based `lastmod`, and no generated search, tag, or archive route appears in the sitemap. | +| Metadata | Every page has a unique title and description, 2–3 controlled tags, and at least three query-oriented keywords. Titles are at most 65 characters and descriptions are 50–180 characters. | +| Content structure | The built page has exactly one H1, at least 50 visible words, and at least one contextual internal link unless it is the site root. Broken links and anchors fail the Docusaurus build. | +| Accessibility | Every image has useful alt text and every embedded tutorial has a non-empty title. | +| Performance | No JavaScript chunk exceeds 250 KB gzip, no canonical HTML file exceeds 250 KB, referenced instructional media stays below 2 MB, and third-party chat loads only after interaction. | +| Freshness | At least 98% of pages are within their review SLA: 180 days for volatile material and 365 days for standard material. | +| Agent discovery | Every canonical page has page-level Markdown, appears in `llms.txt`, belongs to at least one bounded topic pack, and is present in the agent manifest. No topic pack exceeds 500,000 characters. | +| Structured data | Every built documentation page includes valid `TechArticle` JSON-LD with a canonical URL and publisher. | +| Retrieval quality | On the fixed intent set: recall@5 ≥98%, top-1 accuracy ≥90%, and canonical evidence coverage ≥98%. | +| Live answer quality | On a separately approved and recorded model run: answer correctness ≥95%, citation support ≥98%, and unsupported-claim rate <1%. This is not inferred from the static retrieval score. | + +## Required front matter + +Every page must include: + +```yaml +--- +slug: /canonical-route +title: Task-specific title +description: A unique 50–180 character summary that says what the reader can accomplish. +tags: [FlutterFlow, Controlled Product Area] +keywords: [FlutterFlow, user query phrase, feature name] +last_verified: 2026-09-01 +--- +``` + +Only add `last_verified` after checking the instructions against the current product. Metadata cleanup, link checking, or a successful build alone does not count as product verification. + +## Page design for answer engines + +A task guide should state the outcome in its opening paragraph and use this order when relevant: + +1. What the feature does and when to use it. +2. Availability, plan, platform, and prerequisite constraints. +3. Numbered steps using current UI labels and navigation paths. +4. A verifiable expected result. +5. Common failure modes and safe recovery steps. +6. Related canonical guides. + +Put critical facts in text. Images and videos supplement the procedure; they do not replace it. Use exact FlutterFlow UI labels in bold. Prefer one canonical page per intent and link aliases or broader overviews to it. + +## Terminology that agents must distinguish + +- **AI Agent** is the FlutterFlow desktop feature for using external coding agents to edit a FlutterFlow project. +- **AI Agents** is the runtime integration for adding AI-powered experiences to an app. +- **Codex CLI** is the terminal interface. **Codex in the ChatGPT desktop app** is the desktop surface. State which surface a procedure applies to. +- **Test Mode**, **Run Mode**, **Local Run**, and deployed builds are distinct environments. Do not use the names interchangeably. +- **Generated code** describes exported Flutter code. It is not the same as project configuration edited through the FlutterFlow CLI or MCP tools. + +## Freshness workflow + +Volatile sections include integrations, deployment, testing, CLI/agent tooling, accounts and billing, and troubleshooting. They must be verified every 180 days. Other pages must be verified every 365 days. + +For each review: + +1. Reproduce the task in the current product or obtain confirmation from the owning product team. +2. Verify plan, platform, region, and role prerequisites. +3. Confirm every UI label, navigation path, code sample, external link, and expected result. +4. Remove obsolete alternatives and redirect duplicate pages to the canonical guide. +5. Update `last_verified` to the review date and include public evidence in the pull request when appropriate. Keep private source revisions, implementation paths, excerpts, and review notes in an approved private system; never add them to this public repository or its Git history. +6. Run `npm run build` and `npm run audit:seo-agent:built`. + +The audit uses `last_verified` when present. For pages included in the repository-wide SEO migration, it otherwise uses `freshness-baseline.json`, which preserves the last pre-migration content evidence date. New pages fall back to their most recent Git commit. This prevents a metadata-only migration from making old product instructions look newly verified. Stale pages remain visible as warnings until a real product review occurs. + +## Agent artifacts + +The build publishes: + +- `/llms.txt`: canonical page inventory and bounded topic-pack index. +- `/llms-full.txt`: complete canonical corpus for consumers that explicitly want it. +- `/llms/.txt`: focused context packs kept below the configured context budget. +- `/.md`: page-level Markdown with canonical URL, source file, and last-updated metadata. +- `/agent-content-manifest.json`: machine-readable inventory for validation and downstream ingestion. + +Search, tag, blog, and other navigation-only routes are excluded. The postbuild generator reads Docusaurus's resolved metadata, so relative slugs and generated category indexes use the same canonical routes as the rendered site. + +## Commands + +```bash +npm run remediate:docs # Reapply deterministic metadata/accessibility normalization from HEAD +npm run typecheck # Validate theme and component TypeScript +npm run build # Build and generate sitemap/agent artifacts +npm run audit:seo-agent # Source-only scorecard +npm run audit:seo-agent:built +npm run audit:external-links # Network check; review timeouts manually +npm run eval:agent-retrieval +``` + +Do not run the remediation command after making uncommitted manual documentation edits: it intentionally rebuilds documentation files from `HEAD` so the large migration is reproducible. diff --git a/README.md b/README.md index 196c1549d..eed862083 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,8 @@ Either way, you'll need to open up a pull request and get approval from at least ## Contribution Guidelines Before you start contributing, please take a moment to review our [Contribution Guidelines](https://flutterflow.notion.site/Docs-Contribution-Guidelines-42829c305df441f6b061b4095abac8a8). This document outlines the process and expectations for contributions to ensure a smooth collaboration. +All changes must also follow the repository's [documentation search and agent quality standard](CONTENT_QUALITY.md). New task pages should start from [the task-guide template](templates/task-guide.md). Include public evidence in the pull request when appropriate, and keep any private implementation evidence in an approved private system rather than this public repository. + ## How to Contribute 1. **Editing Existing Pages**: To make edits to an existing page in [docs.flutterflow.io](https://docs.flutterflow.io), you can use the "Edit this page" button that appears at the bottom of each page. This button will bring you straight to the source of the page in GitHub. @@ -27,6 +29,7 @@ You may want to run the docs site locally to test and visualize changes you are 1. **Install Dependencies:** Run **`npm install`** in your terminal to install the necessary dependencies. 2. **Preview Changes:** To see your changes in real-time as you edit the files, you can run a local development server. This server will host your website and reflect the latest changes. Use the command **`npm run start`**. +3. **Validate Search and Agent Quality:** Run **`npm run typecheck`**, **`npm run build`**, and **`npm run audit:seo-agent:built`** before opening a pull request. ## Deploying a Staging Preview To share your branch with reviewers before merging, deploy it to a Firebase Hosting preview channel. This builds the site and publishes it to a temporary URL (defaults to a 7-day expiry). diff --git a/docs/accounts-billing/account-management.md b/docs/accounts-billing/account-management.md index d963b6e74..669a0870d 100644 --- a/docs/accounts-billing/account-management.md +++ b/docs/accounts-billing/account-management.md @@ -1,11 +1,19 @@ --- slug: account-management title: Account Management -tags: [] +tags: + - FlutterFlow + - Accounts & Billing toc_max_heading_level: 5 sidebar_position: 1 +description: >- + This section contains information on changing your password, verifying your + email, and deleting your account. +keywords: + - Account Management + - Accounts Billing + - FlutterFlow --- - # Account Management This section contains information on changing your password, verifying your email, and deleting your account. @@ -41,7 +49,7 @@ To check if you have verified your account: If you did not receive a verification email, please follow these steps: 1. Navigate to your [account page in FlutterFlow](https://app.flutterflow.io/account). -2. Check that your email address is correct. If your email is incorrect, please reach out to `support@flutterflow.io` to correct this. +2. Check that your email address is correct. If your email is incorrect, please reach out to `support@flutterflow.io` to correct this. 3. From the **Profile Information** section, select **Verify Email**. You should receive a new confirmation email. If you do not receive the verification email, please contact us at support@flutterflow.io. @@ -62,13 +70,13 @@ This step can not be undone. We will not be able to recover your projects. ### How do I change or update my email address? To change your login email in FlutterFlow: -1. Log into your FlutterFlow account. -2. Go to the dashboard and select your account tile (showing your name and email). -3. Click on **Update Email**. -4. Enter your current email and password. -5. Input your new email and click **Confirm & Log Out**. -6. Verify the new email via the link sent to it. -7. Now, you need to create a new password for your new email address. To do so, click on the **Forgot Password** on the login page and enter your new email address. +1. Log into your FlutterFlow account. +2. Go to the dashboard and select your account tile (showing your name and email). +3. Click on **Update Email**. +4. Enter your current email and password. +5. Input your new email and click **Confirm & Log Out**. +6. Verify the new email via the link sent to it. +7. Now, you need to create a new password for your new email address. To do so, click on the **Forgot Password** on the login page and enter your new email address. 8. You'll receive the password reset link at your new email address. Click the link and reset the password. Now, you are ready to log in with your new email address and password. diff --git a/docs/accounts-billing/manage-custom-domains.md b/docs/accounts-billing/manage-custom-domains.md index 6c85c3020..a993920f3 100644 --- a/docs/accounts-billing/manage-custom-domains.md +++ b/docs/accounts-billing/manage-custom-domains.md @@ -1,30 +1,48 @@ - - +--- +title: Manage Custom Domains +description: >- + All paid plans include one free custom domain, with the option to purchase + more if needed. +tags: + - FlutterFlow + - Accounts & Billing +keywords: + - Manage Custom Domains + - Accounts Billing + - FlutterFlow +last_verified: 2026-09-02 +--- # Manage Custom Domains -All paid plans include one free custom domain, with the option to purchase more if needed. +Paid plans include one custom-domain connection. Additional connections may be purchased; check the current [plan comparison](./new-pricing-comparison.md) and the billing screen for availability and regional pricing. You must obtain the domain itself from a domain registrar. -### How do I purchase additional custom domains? +### Purchase domain connections -To purchase domains, paid users can go to their [**account**](https://app.flutterflow.io/account) page, find the **Custom Domains** section, and click the **Add Domains** button. +For a personal plan, go to your [**Account**](https://app.flutterflow.io/account), find **Custom Domains**, and select **Add Domains**. ![add-domain](imgs/add-domain.avif) -The **Team** owner can purchase domains from the **My Team** page. Under the **Custom Domains** section, click **Add Domains** to add one for the team. +For a team plan, a team owner can open **My Team**, find **Custom Domains**, and select **Add Domains**. ![add-domain-team](imgs/add-domain-team.avif) :::note -Note that purchasing a domain is not possible during the trial period. If you're interested in obtaining a domain, please reach out to our support team for further assistance. +Additional domain connections cannot be purchased during a trial. Contact FlutterFlow support if the billing screen does not offer the connection your plan requires. ::: ### How do I remove custom domains? -To remove the custom domain, paid users can go to their [**account**](https://app.flutterflow.io/account) page, find the **Custom Domains** section, and click **Remove Domains** to remove the existing custom domain. +For a personal plan, open your [**Account**](https://app.flutterflow.io/account), find **Custom Domains**, and select **Remove Domains**. + +A team owner can remove a team's domain connection from **My Team > Custom Domains > Remove Domains**. -The **Team** owner can remove domain from the **My Team** page. In the **Custom Domains** section, click **Remove Domains**. +Removing the FlutterFlow connection does not cancel registration of the domain with your registrar. Confirm which deployed project uses the domain before removing it. ![remove-domain-team](imgs/remove-domain-team.avif) + +## Related documentation + +See [Account Management](/accounts-billing/account-management) for a related FlutterFlow workflow. diff --git a/docs/accounts-billing/new-pricing-comparison.md b/docs/accounts-billing/new-pricing-comparison.md index 27260c8c5..c6ad71a07 100644 --- a/docs/accounts-billing/new-pricing-comparison.md +++ b/docs/accounts-billing/new-pricing-comparison.md @@ -1,11 +1,17 @@ --- slug: plan-comparison -title: "Plan Comparison" -description: "Compare FlutterFlow plans and features to find the right plan for your needs" +title: Plan Comparison +description: Compare FlutterFlow plans and features to find the right plan for your needs hide_table_of_contents: true sidebar_position: 3 +tags: + - FlutterFlow + - Accounts & Billing +keywords: + - Plan Comparison + - Accounts Billing + - FlutterFlow --- - @@ -15,14 +21,14 @@ import {useState, useEffect} from 'react'; export const PricingToggles = () => { const [currency, setCurrency] = useState('USD'); const [billingPeriod, setBillingPeriod] = useState('monthly'); - + // Update sticky header when pricing changes useEffect(() => { // Trigger sticky header recreation when pricing data changes const event = new CustomEvent('pricingChanged'); window.dispatchEvent(event); }, [currency, billingPeriod]); - + const pricingData = { USD: { monthly: { @@ -32,10 +38,10 @@ export const PricingToggles = () => { business: '1st seat: $150, \n Seats 2-5: $85 each*', enterprise: 'Custom' }, - annual: { + annual: { free: 0, individual: 351, // $360/year = $30/month effective - growth: '1st seat: $720, \n 2nd seat: $495', + growth: '1st seat: $720, \n 2nd seat: $495', business: '1st seat: $1,350, \n Seats 2-5: $765*', // $4752/year = $396/month effective enterprise: 'Custom' } @@ -771,3 +777,7 @@ Includes all Business features, plus the ability to add up to 7 additional seats ### Localized Pricing INR pricing reflects localized rates adjusted for local purchasing power, providing the same features and plan structures as USD pricing. All plans include the same comprehensive feature set regardless of currency. + +## Related documentation + +See [Account Management](/accounts-billing/account-management) for a related FlutterFlow workflow. diff --git a/docs/accounts-billing/payments-billing.md b/docs/accounts-billing/payments-billing.md index b92af815e..4413bbb6b 100644 --- a/docs/accounts-billing/payments-billing.md +++ b/docs/accounts-billing/payments-billing.md @@ -1,19 +1,31 @@ - - +--- +title: Payments & Billing +description: >- + This section contains information on the payment methods we accept and how to + change your payment method. +tags: + - FlutterFlow + - Accounts & Billing +keywords: + - Payments & Billing + - Payments Billing + - Accounts Billing +last_verified: 2026-09-02 +--- # Payments & Billing This section contains information on the payment methods we accept and how to change your payment method. ## Invoices -#### Can I Add A Tax ID (e.g. VAT) to my invoice? -If you need to include VAT in your invoices, please reach out to our support team at support@flutterflow.io, and we’ll be happy to assist you with the process. +### Add a tax ID +If the billing portal does not let you add the required tax information, contact [FlutterFlow support](mailto:support@flutterflow.io) before the invoice is issued. Tax treatment depends on your billing country and account details. ## Payment Methods ### What payment methods do you accept? -We currently accept Visa, Mastercard, American Express, and JCB. +The billing checkout displays the payment methods currently available for your account and region. Commonly supported cards include Visa, Mastercard, American Express, and JCB. ### Can I use a gift card in addition to my credit card? -At this time we are unable to process Gift Card payments. +Gift cards are not supported as a second payment method for a subscription. ### My payment failed, how can I change to a different credit card? @@ -34,11 +46,11 @@ You can use these steps to update your payment method on an open invoice (where 5. Enter your updated payment information -Once your updated transaction is successfully completed, your system access will be restored. +After the outstanding transaction succeeds, allow the account page to refresh. If paid access is not restored, contact support with the invoice identifier—never send full card details. ### I used the wrong credit card, can I change it? -Once your subscription has been purchased, we unfortunately are unable to change your payment method for this month. +Changing the default payment method applies to future charges; it does not move a charge that has already completed to a different card. You can change your default payment method for next month's purchase using these steps: @@ -50,4 +62,8 @@ You can change your default payment method for next month's purchase using these :::note You can change the default payment method by selecting the three dots next to the payment method and then selecting **Make Default.** -::: \ No newline at end of file +::: + +## Related documentation + +See [Account Management](/accounts-billing/account-management) for a related FlutterFlow workflow. diff --git a/docs/accounts-billing/plan-pricing.md b/docs/accounts-billing/plan-pricing.md index 180d33135..9f34ac3a9 100644 --- a/docs/accounts-billing/plan-pricing.md +++ b/docs/accounts-billing/plan-pricing.md @@ -1,12 +1,19 @@ --- slug: plan-pricing title: Plans & Pricing -tags: [] +tags: + - FlutterFlow + - Accounts & Billing toc_max_heading_level: 5 sidebar_position: 2 hide_table_of_contents: true +description: 'For our most up-to-date information, please visit FlutterFlow pricing .' +keywords: + - Plans & Pricing + - Plan Pricing + - Accounts Billing +last_verified: 2026-09-02 --- - import Head from '@docusaurus/Head'; import ThemedImage from '@theme/ThemedImage'; @@ -16,18 +23,21 @@ import ThemedImage from '@theme/ThemedImage'; # Plans & Pricing :::info -For our most up-to-date information, please visit **[FlutterFlow pricing](https://flutterflow.io/pricing)**. -Regional discounts are available, please **[log in to FlutterFlow](https://app.flutterflow.io/)** to see the pricing for your region. +For current prices and features, use the [FlutterFlow pricing page](https://flutterflow.io/pricing), the [plan comparison](./new-pricing-comparison.md), and the checkout shown after you [log in to FlutterFlow](https://app.flutterflow.io/). Prices, taxes, currencies, promotions, and regional discounts can vary; the checkout for your account is authoritative. ::: -## Pricing Update [June 2025] +## 2025 pricing migration archive + +:::warning[Historical information] +The remainder of this page records the 2025 migration from the legacy Standard, Pro, and Teams plans to Free, Basic, Growth, and Business. Its deadlines and transition offers have passed. Do not use this archive to quote current prices, limits, discounts, or eligibility. +::: -FlutterFlow has evolved significantly, from a visual builder to a complete development environment with features like code export, GitHub integration, branching, AI agents, and app deployment tools. As the platform has matured, so have the ways people use it. To better reflect how teams build and scale today, we're introducing updated pricing plans. These updates will help us continue improving the platform, supporting your workflows, and delivering the advanced features needed for building production-ready apps. +FlutterFlow announced an updated pricing and packaging model in June 2025 as the platform expanded beyond its earlier plan structure. ### What's Changing? -As part of broader improvements to the platform, FlutterFlow is updating its pricing and packaging model effective **August 18, 2025**. The update introduces new plan tiers aligned with team size, simplifies billing, and ensures better alignment between user needs and platform capabilities. +The pricing and packaging model took effect for new users on **August 18, 2025**, followed by the documented migration period for existing users. **Key Changes** @@ -388,7 +398,7 @@ No. As a part of the existing Teams plan retirement, team size will be locked on I am currently on a Teams plan with 6+ users and do not want to migrate to the Enterprise plan – how do I stay on the Business tier and how will I be charged?

-- Teams with more than 5 users who do not wish to move yet to an Enterprise contract can continue on the Business tier under a transitional pricing structure. These teams will be billed at the standard Business tier seat pricing and then $85/seat/month for each additional seat over 5. Pricing will be based on the number of users in the team as of September 18, 2025 and billed on a monthly basis. +- Teams with more than 5 users who do not wish to move yet to an Enterprise contract can continue on the Business tier under a transitional pricing structure. These teams will be billed at the standard Business tier seat pricing and then $85/seat/month for each additional seat over 5. Pricing will be based on the number of users in the team as of September 18, 2025 and billed on a monthly basis.

- This option allows larger retail teams to continue operating under the Business feature set without immediate contract negotiation, but will be available only to existing 6+ seat teams for 12 months from September 18, 2025 through September 18, 2026 to ensure continuity without immediate contract negotiation. @@ -406,7 +416,7 @@ However, if you would like to maintain a single account, collaboration across al Can I belong to multiple teams? How will that be billed?

-Yes, starting August 18, 2025, users will be able to belong to multiple teams in FlutterFlow in the new plans – this is a new capability as part of our updated team and collaboration structure. Each team is treated as a separate billing entity, with its own plan, users, and usage limits. +Yes, starting August 18, 2025, users will be able to belong to multiple teams in FlutterFlow in the new plans – this is a new capability as part of our updated team and collaboration structure. Each team is treated as a separate billing entity, with its own plan, users, and usage limits.

If you are added as an editor on more than one team, you will count toward the seat total on each of those teams, and each team will manage your seat and billing as part of their own subscription. You will not be billed individually – all billing remains centralized at the team level. diff --git a/docs/accounts-billing/privacy-terms-of-service.md b/docs/accounts-billing/privacy-terms-of-service.md index 2e9563628..c509d4439 100644 --- a/docs/accounts-billing/privacy-terms-of-service.md +++ b/docs/accounts-billing/privacy-terms-of-service.md @@ -1,12 +1,25 @@ - - +--- +title: Privacy And Terms Of Service +description: >- + How do I request the deletion of my personal data? To request deletion of your + personal data, please reach out to our support team at support@flutterflow.io + How do I request a c... +tags: + - FlutterFlow + - Accounts & Billing +keywords: + - Privacy And Terms Of Service + - Privacy Terms Of Service + - Accounts Billing +last_verified: 2026-09-02 +--- # Privacy And Terms Of Service ### How do I request the deletion of my personal data? To request deletion of your personal data, please reach out to our support team at support@flutterflow.io ### How do I request a copy of my personal data? -To request deletion of your personal data, please reach out to our support team at support@flutterflow.io. +To request a copy of your personal data, contact [FlutterFlow support](mailto:support@flutterflow.io) from the email address associated with your account. FlutterFlow may need to verify your identity before fulfilling the request. ### How do I unsubscribe from email communications / marketing emails? To unsubscribe from FlutterFlow emails, please click the “Unsubscribe” link in the footer of our emails. @@ -15,4 +28,8 @@ To unsubscribe from FlutterFlow emails, please click the “Unsubscribe” link You can review the most recent version of our Privacy Policy [on the website](https://www.flutterflow.io/privacy). ### Where can I view your Terms of Service (ToS)? -You can review the most recent version of our Terms of Service [linked on the website](https://www.flutterflow.io/tos). \ No newline at end of file +You can review the most recent version of our Terms of Service [linked on the website](https://www.flutterflow.io/tos). + +## Related documentation + +See [Account Management](/accounts-billing/account-management) for a related FlutterFlow workflow. diff --git a/docs/accounts-billing/referral-program.md b/docs/accounts-billing/referral-program.md index 45c091da5..be7814909 100644 --- a/docs/accounts-billing/referral-program.md +++ b/docs/accounts-billing/referral-program.md @@ -1,8 +1,25 @@ - +--- +title: Referral Program +description: >- + With the retirement of the Pro plan, the existing referral program has been + discontinued. +tags: + - FlutterFlow + - Accounts & Billing +keywords: + - Referral Program + - Accounts Billing + - FlutterFlow +last_verified: 2026-09-02 +--- # Referral Program :::warning[Discontinued] With the retirement of the Pro plan, the existing referral program has been discontinued. Any active referral discounts will end at your next renewal. However, referral credits you’ve already earned will remain in your account and can be redeemed for free months on the new Growth plan. -We are also exploring new referral and incentive programs to better support and reward our community under the updated pricing model. +For current promotions or incentive programs, rely on notices in your FlutterFlow account or official FlutterFlow announcements; this page documents only the discontinued referral program. ::: + +## Related documentation + +See [Account Management](/accounts-billing/account-management) for a related FlutterFlow workflow. diff --git a/docs/accounts-billing/subscriptions/refund.md b/docs/accounts-billing/subscriptions/refund.md index 4c4dde276..a7decd1e5 100644 --- a/docs/accounts-billing/subscriptions/refund.md +++ b/docs/accounts-billing/subscriptions/refund.md @@ -1,13 +1,21 @@ --- slug: refunds title: Refunds -tags: [] +tags: + - FlutterFlow + - Accounts & Billing toc_max_heading_level: 5 sidebar_position: 4 +description: >- + If you're not happy with your FlutterFlow subscription, you can cancel at any + time. +keywords: + - Refunds + - Subscriptions + - Accounts Billing +last_verified: 2026-09-02 --- - - # Refunds If you're not happy with your FlutterFlow subscription, you can [cancel at any time](./subscriptions.md#cancel-my-plan). -However, there are no refunds for cancellation. In the event that the Company suspends or terminates your Account or these Terms, you understand and agree that you shall receive no refund, whether for any unused time on a subscription, any license or subscription fees for any portion of the Service, any content or data associated with your User Account, or for anything else. \ No newline at end of file +Cancellation does not ordinarily provide a refund for unused subscription time or prepaid fees. The controlling policy is the current [FlutterFlow Terms of Service](https://flutterflow.io/tos); contact [FlutterFlow support](mailto:support@flutterflow.io) for account-specific questions or where applicable law may require different treatment. diff --git a/docs/accounts-billing/subscriptions/subscriptions.md b/docs/accounts-billing/subscriptions/subscriptions.md index c757b2cf5..1b66699e9 100644 --- a/docs/accounts-billing/subscriptions/subscriptions.md +++ b/docs/accounts-billing/subscriptions/subscriptions.md @@ -1,22 +1,30 @@ --- slug: subscriptions title: Subscriptions -tags: [] +tags: + - FlutterFlow + - Accounts & Billing toc_max_heading_level: 5 sidebar_position: 0 +description: >- + This section provides information on free trials, plan changes, and other + subscription-related questions. +keywords: + - Subscriptions + - Accounts Billing + - FlutterFlow +last_verified: 2026-09-02 --- - - # Subscriptions This section provides information on free trials, plan changes, and other subscription-related questions. ## Free Trials -The first paid plan you purchase will come with a free 14-day trial. For 14 days, you will have access to the features of the plan you selected before you are charged. If you can cancel your subscription during this 14-day trial, you will not be charged. +When the checkout offers a 14-day free trial for your first paid plan, you can use that plan's features during the trial and cancel before the displayed charge date to avoid the first subscription charge. Confirm the offer and charge date shown at checkout because promotions and eligibility can change. :::info -The 14-day trial applies only to your first paid plan. Any later plan (Basic, Growth, or Business) won’t include a trial, even if the first plan is still in trial. +The standard trial is limited to the first eligible paid-plan purchase. Do not assume a later Basic, Growth, or Business subscription includes another trial; the checkout is authoritative for your account. ::: @@ -32,7 +40,7 @@ To start a free trial, please follow these steps: ### What happens at the end of the trial period? -At the end of your trial period, your payment method will be charged. You can cancel at any time during the trial period. +Unless you cancel before the charge date displayed in billing, the selected subscription renews into a paid plan at the end of the trial. ## Upgrade Plan @@ -84,7 +92,7 @@ You can view the next billing cycle date in the "My Plan" section of the [Flutte ![renew](../imgs/renew.png) -The next billing cycle date for this plan is September 12, 2025. +The date in the screenshot is an example. Use the renewal date shown in your own billing portal. ### Do subscriptions renew automatically? @@ -100,16 +108,14 @@ We are unable to transfer a paid FlutterFlow subscription to another FlutterFlow ### If I have a paid plan, will project collaborators be able to use paid features? -No. Having a paid plan yourself does not give your project collaborators access to paid features. Starting **September 17, 2025**, all collaboration must happen within a **Growth, Business, or Enterprise plan**, and every collaborator must have a **paid seat** in that team to have full edit access. Anyone not on your team will be switched to **view-only** until added as a paid team member. +No. A personal paid plan does not give project collaborators paid features. Full team edit access uses a **Growth**, **Business**, or **Enterprise** team plan, and each editor needs the appropriate paid team seat or eligible project-collaborator access. A collaborator without that access is view-only. ### If I upgrade from the Growth Plan to the Business Plan in the middle of my billing cycle, will I be charged for both plans? -Upgrades are automatic, so the system will count the remaining days from the Growth plan and reduce it from the Business Plan price. - -For example, if you paid $80 for Growth and you have 15 days remaining in the billing cycle, then on upgrading to Business (let's say priced at $150), you will eventually pay $(150-40) = $110. +The billing portal calculates the upgrade charge and any credit for the unused portion of the current plan. Review the invoice preview before confirming; do not calculate the final charge from documentation examples because pricing, tax, currency, and remaining time vary. :::info FlutterFlow provides different pricing options depending on your region. To see the exact prices for your area, visit the [**Plans & Pricing**](../plan-pricing.md) page. -::: \ No newline at end of file +::: diff --git a/docs/ff-concepts/adding-customization/cloud-functions.md b/docs/ff-concepts/adding-customization/cloud-functions.md index 2cbf87acf..4474bb22e 100644 --- a/docs/ff-concepts/adding-customization/cloud-functions.md +++ b/docs/ff-concepts/adding-customization/cloud-functions.md @@ -1,12 +1,19 @@ --- slug: /concepts/custom-code/cloud-functions title: Cloud Functions -description: Learn how to use Cloud Functions in your FlutterFlow app for serverless backend functionality. -tags: [Cloud Functions, Serverless, Integration] +description: >- + Learn how to use Cloud Functions in your FlutterFlow app for serverless + backend functionality. +tags: + - FlutterFlow + - Concepts sidebar_position: 7 -keywords: [FlutterFlow, Cloud Functions, Serverless, Integration] +keywords: + - FlutterFlow + - Cloud Functions + - Serverless + - Integration --- - # Cloud Functions Cloud Functions let you run backend code in response to events and API requests without managing your own servers. They are commonly used for tasks such as processing data, calling external APIs, sending notifications, running AI workflows, or securely handling secrets and business logic. @@ -20,7 +27,7 @@ FlutterFlow supports both Firebase Cloud Functions and Supabase Edge Functions, FlutterFlow includes built-in support for creating, editing, deploying, and triggering Firebase Cloud Functions directly from the platform. :::note -Read up on some interesting use cases of +Read up on some interesting use cases of [**Cloud Functions**](https://firebase.google.com/docs/functions/use-cases). ::: @@ -28,8 +35,7 @@ Read up on some interesting use cases of Let's see how to add a *Cloud Function* by building an example that generates logos based on user prompts. Here's how it looks: -

+

@@ -46,10 +52,10 @@ Here are the step-by-step instructions to build such an example: **1. Add page state variables** -For this example, you'll need to set up two +For this example, you'll need to set up two [Page State variables](../../resources/ui/pages/page-lifecycle.md#creating-a-page-state): -1. **generatingImage (*****Type: Boolean*****)**: This is used to control the visibility of a +1. **generatingImage (*****Type: Boolean*****)**: This is used to control the visibility of a loading indicator during the logo creation process. Its value is set to *True* before initiating the API call and switched to *False* once the logo generation is complete. 2. **logoImage (*****Type: ImagePath*****)**: This is used to hold the generated logo image. After a successful API call, the retrieved image URL is stored here, allowing the logo to be displayed in the Image widget. @@ -73,8 +79,8 @@ Few things to note here: To create and deploy a *Cloud Function* : -1. Click on the **Cloud Functions** from the -[**Navigation Menu**](../../../docs/intro/ff-ui/builder.md#navigation-menu) (left side of your +1. Click on the **Cloud Functions** from the +[**Navigation Menu**](../../../docs/intro/ff-ui/builder.md#navigation-menu) (left side of your screen). 2. Click **+ Add**. This will add the default `newCloudFunction`. 3. Set the **Cloud Function Name**. @@ -82,7 +88,7 @@ To create and deploy a *Cloud Function* : #### Boilerplate Settings On the right side, you can configure the following Boilerplate Settings: -1. **Memory Allocation**: You can specify the amount of memory your function should have when +1. **Memory Allocation**: You can specify the amount of memory your function should have when it's executed based on its complexity and needs. This setting is crucial as it influences the function's performance and the cost of running it. More memory can enhance performance for intensive tasks but also increase costs. 2. **Timeout (s)**: This refers to the maximum amount of time, in seconds, that a function is allowed to run before it is automatically terminated. If your function takes longer to execute, increasing the timeout setting may be necessary. However, be aware that longer timeouts can incur higher costs since billing is based on execution time. @@ -93,20 +99,20 @@ On the right side, you can configure the following Boilerplate Settings: #### Configuring Input & Output -Your cloud function might need some data to process and return the result. You can do so +Your cloud function might need some data to process and return the result. You can do so by configuring the input and output. -1. To receive output from a Cloud Function, enable the **Return Value** and choose an +1. To receive output from a Cloud Function, enable the **Return Value** and choose an appropriate Type for the output, like 'String' for text. For this example, set it to *ImagePath* to get the URL of the generated logo. 2. To input data: Click **+ Add parameters**. **Name** the parameter, select its **Type**, choose single or multiple items (**Is List** option), and uncheck **Nullable** if the value can be null. For this example, add a parameter 'prompt' with *Type* set to *String*. -3. When using [Custom Data Types](../../resources/data-representation/custom-data-types.md), +3. When using [Custom Data Types](../../resources/data-representation/custom-data-types.md), Cloud Function expects JSON, matching each field in the Data Type to a key-value pair in the JSON. If the Data Type is a list, the function expects a list of JSONs. For example, for a custom data type named 'Person' with fields 'Name' and 'Age,' the function should return: ``` //JSON: { "Name": "John", "Age": 30 } - + //Example Cloud Function Code: return { "name": person.name, @@ -115,12 +121,12 @@ by configuring the input and output. ``` For a list, the function should return: - - + + ``` //JSON [ { "Name": "John", "Age": 30 }, { "Name": "Jane", "Age": 25 } ] - + //Example Cloud Function Code: return filteredpersons.map(filteredpersons => { return { @@ -129,12 +135,12 @@ For a list, the function should return: }; }); ``` - + #### To deploy -1. Click the `[]` icon to view the boilerplate code; a popup will open with the updated +1. Click the `[]` icon to view the boilerplate code; a popup will open with the updated code, and then click **` Copy to Editor`**. **Tip**: To see if you are able to deploy the cloud function (before adding your own code), proceed directly with steps 8 and 9. -2. Inside the code editor, add the cloud function code. **Tip**: You can copy the boilerplate code +2. Inside the code editor, add the cloud function code. **Tip**: You can copy the boilerplate code to [ChatGPT](https://chat.openai.com/) and ask it to write the desired code based on that. 3. Click **Save Cloud Function**. 4. Click **Deploy**. @@ -214,8 +220,7 @@ exports.logoMaker = functions.region('us-central1') Always regenerate and use the updated boilerplate code or adjust your own code accordingly whenever there are changes in the code, boilerplate settings, or input/output parameters. ::: -
+

@@ -233,8 +238,7 @@ To add a dependency, open the `package.json` file and specify your package in th The newly created *Cloud Function* will be available as an action when you are adding one. For this example, on click of a button, we'll first set the *generatingImage*to *True* and then trigger the **Cloud Function Action**. -
+


@@ -244,8 +248,7 @@ To use the *Could Function* result, ensure you provide the *Action Output Variab For this example, we'll use the result (i.e., generated logo image URL) and set it to *logoImage* variable. Here's how you do it: -
+
### Testing Cloud Functions @@ -362,9 +365,8 @@ Here's how it looks: paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding height: 0, width: '100%'}}> -

- -9. By default, the custom dialog appears in the center of the screen. However, you can use the **Dialog Alignment** property to decide where to position the dialog on the screen. - + +8. Use **Dialog Alignment** to position a global custom dialog within the screen. Its default alignment is centered. + ![Align custom dialog](imgs/align-custom-dialog.avif) - -10. To position the dialog around the widget that opened it, enable the **Align with the Target Widget**, and then align using the **Target Alignment** property. **Tip**: If dialog goes out of the screen, enable **Avoid Overflow**. + +9. To position the dialog relative to the widget that opened it, enable **Align with the Target Widget**, then combine **Target Alignment** with **Dialog Alignment**. Enable **Avoid Overflow** if the aligned dialog would extend beyond the screen.
-
-

\ No newline at end of file +

+ +### Returning a value from a custom dialog + +Add **Dismiss Custom Dialog** to a widget inside the displayed component and enable its **Has Value** option. FlutterFlow derives the custom dialog's output type from that dismiss action. Back on the opening **Custom Dialog** action, set **Action Output Variable Name** and use that output in later actions. + +All value-returning dismiss actions in the same component must use the same type. Keep **Non-Blocking** off when the next action depends on the returned value. See [Dismiss Custom Dialog](dismiss-custom-dialog.md) for the complete workflow. diff --git a/docs/ff-concepts/alerts/dismiss-custom-dialog.md b/docs/ff-concepts/alerts/dismiss-custom-dialog.md index c3b3d2b7f..36a4ed13a 100644 --- a/docs/ff-concepts/alerts/dismiss-custom-dialog.md +++ b/docs/ff-concepts/alerts/dismiss-custom-dialog.md @@ -2,22 +2,30 @@ title: Dismiss Custom Dialog slug: /concepts/alerts/dismiss-custom-dialog sidebar_position: 1 -tags: [Actions, Alerts & Notifications] -keywords: [FlutterFlow, Actions, Alerts & Notifications, Dismiss Custom Dialog] +tags: + - FlutterFlow + - Concepts +keywords: + - FlutterFlow + - Actions + - Alerts & Notifications + - Dismiss Custom Dialog +description: >- + Close a FlutterFlow custom dialog from its component and optionally return a + typed value to the action flow that opened it. +last_verified: 2026-09-01 --- - # Dismiss Custom Dialog -With this action, you can easily close the [custom dialog](alert-dialog.md#adding-custom-dialog-action), providing a convenient way for users to dismiss it. This functionality is handy when you want to give users the option to close the dialog from any widget within it, like a close button. +Use **Dismiss Custom Dialog** on a widget inside the component displayed by a [custom dialog](alert-dialog.md#adding-custom-dialog-action). The action closes the active dialog. It can also return a typed result—such as a selected color, record, or confirmation status—to the **Custom Dialog** action that opened the component.
-
-

\ No newline at end of file +

+ +## Related documentation + +See [Alert Dialog](/concepts/alerts/alert-dialog) for a related FlutterFlow workflow. diff --git a/docs/ff-concepts/animations/animation_gifs/hero-animation-image-widget.gif b/docs/ff-concepts/animations/animation_gifs/hero-animation-image-widget.gif deleted file mode 100644 index 6d1264f2b..000000000 Binary files a/docs/ff-concepts/animations/animation_gifs/hero-animation-image-widget.gif and /dev/null differ diff --git a/docs/ff-concepts/animations/animation_gifs/hero-animation-image-widget.mp4 b/docs/ff-concepts/animations/animation_gifs/hero-animation-image-widget.mp4 new file mode 100644 index 000000000..5b9d26e96 Binary files /dev/null and b/docs/ff-concepts/animations/animation_gifs/hero-animation-image-widget.mp4 differ diff --git a/docs/ff-concepts/animations/animation_gifs/st.gif b/docs/ff-concepts/animations/animation_gifs/st.gif deleted file mode 100644 index ebbae9bcd..000000000 Binary files a/docs/ff-concepts/animations/animation_gifs/st.gif and /dev/null differ diff --git a/docs/ff-concepts/animations/animation_gifs/st.mp4 b/docs/ff-concepts/animations/animation_gifs/st.mp4 new file mode 100644 index 000000000..4d5aadb03 Binary files /dev/null and b/docs/ff-concepts/animations/animation_gifs/st.mp4 differ diff --git a/docs/ff-concepts/animations/animations.md b/docs/ff-concepts/animations/animations.md index c6b298ced..d560f86ae 100644 --- a/docs/ff-concepts/animations/animations.md +++ b/docs/ff-concepts/animations/animations.md @@ -1,22 +1,31 @@ --- slug: /concepts/animations title: Animations -description: Learn the basics of animations in FlutterFlow. -tags: [Animations, Concepts] +description: >- + Enhancing your app with animations significantly improves the user experience, + making it more engaging and intuitive. +last_verified: 2026-09-02 +tags: + - FlutterFlow + - Concepts sidebar_position: 1 -keywords: [FlutterFlow, Animations, Concepts] +keywords: + - FlutterFlow + - Animations + - Concepts --- +# Animations -Enhancing your app with animations significantly improves the user experience, making it more engaging and intuitive. In FlutterFlow, you have several options to add animations to your app: +FlutterFlow provides several animation systems. Choose the system based on what needs to change and what starts the motion: - [**Widget Animations**](widget_animations.md): Add animation effects to an entire widget. -- [**Implicit Animations**](implicit_animations.md): Animate changes in specific widget properties, such as the height of a Container. +- [**Implicit Animations**](implicit_animations.md): Animate runtime changes to supported Container or Transform properties. - [**Hero Animations**](hero_animations.md): Animate a widget that transitions smoothly between screens, also known as shared element transitions. - [**Page Transition Animations**](page_transitions.md): Specify transitions between pages within your app. -- **Import Animations**: Import animations you've created using other tools such [lottiefiles](import-animations/lottie-animation.md) and [Rive](import-animations/rive-animation.md). +- **Imported Animations**: Display and control animations created with tools such as [Lottie](import-animations/lottie-animation.md) and [Rive](import-animations/rive-animation.md). - [**Shaders**](shaders.md): Add GPU-powered visual effects like animated backgrounds, distortions, and interactive touch-based visuals to enhance your UI. To learn more about animations in FlutterFlow, check out this video:
- \ No newline at end of file + diff --git a/docs/ff-concepts/animations/hero_animations.md b/docs/ff-concepts/animations/hero_animations.md index 738f5352e..202bc928e 100644 --- a/docs/ff-concepts/animations/hero_animations.md +++ b/docs/ff-concepts/animations/hero_animations.md @@ -1,38 +1,44 @@ --- slug: /concepts/animations/hero-animations title: Hero Animations -description: Learn how to add Hero Animations in your FlutterFlow app. -tags: [Hero Animations, Concepts] +description: >- + Create shared-element Hero transitions between FlutterFlow pages using + matching tags on Image, Circle Image, or component instances. +last_verified: 2026-09-02 +tags: + - FlutterFlow + - Concepts sidebar_position: 3 -keywords: [FlutterFlow, Hero Animations, Concepts] +keywords: + - FlutterFlow + - Hero Animations + - Concepts --- - # Hero Animation -"Hero" is a widget that gracefully transitions from one screen to another. For instance, on a product listing page, clicking on a product's image triggers a smooth animation where the image flies to a new screen, revealing detailed information about the product. +A Hero animation is a shared-element transition between routes. FlutterFlow wraps the source and destination widgets in Flutter `Hero` widgets; matching **Hero Tag** values tell Flutter which two elements should animate between the pages. ## Creating Hero Animation Let's how to create hero animation with an example that looks like the one below: -![hero-animation-image-widget.gif](animation_gifs/hero-animation-image-widget.gif) + :::info -Building Hero Animation requires you to have at least two pages that share the same image. +The source and destination need matching Hero tags. Their visual content can differ, although similar size and appearance usually produce a smoother transition. Each active route must not contain multiple visible Hero widgets with the same tag. ::: The steps to build such an example are as follows: -1. On the first page, select the image, head over to the properties panel, enable **Use Hero Animation**, and **Add Hero Tag**. +1. On the source page, select an **Image** or **Circle Image**, enable **Use Hero Animation**, and select **+ Add Hero Tag** to create a tag.
-

+ +## Related documentation + +See [Animations](/concepts/animations) for a related FlutterFlow workflow. diff --git a/docs/ff-concepts/animations/import-animations/lottie-animation.md b/docs/ff-concepts/animations/import-animations/lottie-animation.md index 3eec79f50..356315a32 100644 --- a/docs/ff-concepts/animations/import-animations/lottie-animation.md +++ b/docs/ff-concepts/animations/import-animations/lottie-animation.md @@ -1,17 +1,23 @@ --- slug: /concepts/animations/lottie-animation title: Lottie Animation -description: Learn how to add Lottie animation in your FlutterFlow app. -tags: [Lottie Animation, FlutterFlow, Animations] +description: Add local or network Lottie JSON animations in FlutterFlow, configure playback and sizing, and control them with an Animation action. +tags: + - FlutterFlow + - Concepts sidebar_position: 1 -keywords: [Lottie Animation, FlutterFlow, Animations] +keywords: + - Lottie Animation + - FlutterFlow + - Animations +last_verified: 2026-09-02 --- import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; # Lottie Animation -The LottieAnimation widget allows you to display [Lottie files](https://lottiefiles.com/featured) from uploaded assets or the URL link. Lottie files are high quality (they do not pixelate), smaller than GIF, and easy to add to any platform. +The **LottieAnimation** widget renders a Lottie JSON animation from an uploaded asset or a network URL. It is useful for loading indicators, illustrations, and other vector-based motion. For example, you could use the LottieAnimation widget to show a nicely animated loading indicator to provide a great user experience to the users. @@ -20,9 +26,8 @@ For example, you could use the LottieAnimation widget to show a nicely animated paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding height: 0, width: '100%'}}> - -

\ No newline at end of file +

+ +## Troubleshooting + +| Symptom | What to check | +| --- | --- | +| The animation does not load | Confirm the source selection, JSON format, direct URL, network access, and host CORS policy. | +| Box Fit or Frame Rate behaves unexpectedly | Reselect the asset or re-enter the network path so FlutterFlow can read the composition's original dimensions and frame rate. | +| An action does not start playback | Disable **Auto Animate**, select the correct same-page LottieAnimation, and verify the animation type. | +| A looping action cannot pause | Enable **Allow Play/Pause**. This option is available only for Loop and Boomerang. | +| Playback is janky | Reduce composition complexity or dimensions, avoid unnecessary frame-rate overrides, and profile on the target device. | + +## Related documentation + +See [Rive Animation](/concepts/animations/rive-animation) for a related FlutterFlow workflow. diff --git a/docs/ff-concepts/animations/import-animations/rive-animation.md b/docs/ff-concepts/animations/import-animations/rive-animation.md index 729d72a54..dfd86023c 100644 --- a/docs/ff-concepts/animations/import-animations/rive-animation.md +++ b/docs/ff-concepts/animations/import-animations/rive-animation.md @@ -1,23 +1,33 @@ --- slug: /concepts/animations/rive-animation title: Rive Animation -description: Learn how to add Rive animation in your FlutterFlow app. -tags: [Rive Animation, FlutterFlow, Animations] +description: Import a Rive runtime file into FlutterFlow, select its artboard and linear animations, and control playback with an Animation action. +tags: + - FlutterFlow + - Concepts sidebar_position: 2 -keywords: [Rive Animation, FlutterFlow, Animations] +keywords: + - Rive Animation + - FlutterFlow + - Animations +last_verified: 2026-09-02 --- - # Rive Animation -[Rive](https://rive.app/) is a real-time interactive design and animation tool. Using the **RiveAnimation** widget you can easily import your Rive assets to FlutterFlow and use them inside your app. +[Rive](https://rive.app/) is a design and animation tool. The **RiveAnimation** widget loads a `.riv` runtime file, displays a selected artboard, and plays one or more linear animations from that artboard. + +:::warning + +FlutterFlow's RiveAnimation widget currently supports linear animations, not Rive state-machine animations. If the selected artboard contains no linear animations, FlutterFlow asks you to select a different file or artboard. + +:::
-

+ +## Troubleshooting + +| Symptom | What to check | +| --- | --- | +| Artboard and animation controls never appear | Confirm that the path returns a valid `.riv` runtime file directly, or reselect the uploaded asset. | +| FlutterFlow reports no linear animations | The artboard may contain only a state machine. Add a linear animation or select another artboard. | +| Continuous is not available | At least one selected animation must be authored with Loop or Ping Pong behavior. | +| An action does not start playback | Disable **Auto Animate**, confirm the same-page target, and check the animation type and selected animation list. | +| A network file works in one target but not another | Check HTTPS access, redirects, authorization, browser CORS, and whether the URL returns the `.riv` bytes directly. | + +## Related documentation + +See [Lottie Animation](/concepts/animations/lottie-animation) for a related FlutterFlow workflow. diff --git a/docs/ff-concepts/animations/page_transitions.md b/docs/ff-concepts/animations/page_transitions.md index 9994751e4..c55c0935f 100644 --- a/docs/ff-concepts/animations/page_transitions.md +++ b/docs/ff-concepts/animations/page_transitions.md @@ -1,11 +1,20 @@ --- slug: /concepts/animations/page-transition title: Page Transition Animations -description: Learn how to add page transition animations in your FlutterFlow app. -tags: [Page Transition Animations, Concepts] +description: >- + Configure per-action and app-wide page transitions in FlutterFlow, including + transition type, duration, and override precedence. +last_verified: 2026-09-02 +tags: + - FlutterFlow + - Concepts sidebar_position: 4 -keywords: [FlutterFlow, Page Transition Animations, Concepts] +keywords: + - FlutterFlow + - Page Transition Animations + - Concepts --- +# Page Transition Animations The animation that plays while transitioning from one page of the app to another is known as a page transition. In FlutterFlow, you can customize this animation to enhance the user experience. @@ -18,7 +27,7 @@ Here, the transitions are recorded with the duration set to 1000ms to make the a | Transition Type | Description | Example | |-----------------|------------------------------------------------|---------------------------| | Instant | Transition with no animation, switching pages immediately. | ![Instant](animation_gifs/instant-page-transitions.gif) | -| Fade In | Gradually fades the new page into view. | ![Fade In](animation_gifs/fade-page-transitions.gif) | +| Fade | Gradually fades the new page into view. | ![Fade](animation_gifs/fade-page-transitions.gif) | | Slide Up | Slides the new page up from the bottom. | ![Slide Up](animation_gifs/slide-up-page-transition.gif) | | Slide Down | Slides the new page down from the top. | ![Slide Down](animation_gifs/slide-down-page-transition.gif) | | Slide Left | Slides the new page in from the right. | ![Slide Left](animation_gifs/slide-left-page-transition.gif) | @@ -27,22 +36,30 @@ Here, the transitions are recorded with the duration set to 1000ms to make the a ## Animate single navigate transition -To set a transition animation for a single navigate action, first, ensure that you have added a [**Navigate To**](../../ff-concepts/navigation-routing/page-navigation.md#navigate-to-action) action and then select an animation from the **Transition Type** dropdown. By default, the animations use 300 milliseconds as the duration for which it plays but you can change it by specifying a value inside the **Duration** (ms) field. +To set a transition for one navigation, add a [**Navigate To**](../../ff-concepts/navigation-routing/page-navigation.md#navigate-to-action) action and select **Transition Type**. The choices are **Default**, **Instant**, **Fade**, **Slide Up**, **Slide Down**, **Slide Left**, **Slide Right**, and **Scale**. + +**Default** inherits the app-wide override when one is enabled; otherwise FlutterFlow uses the normal route behavior. A non-instant custom transition uses **Duration (ms)**. If neither the action nor the global override supplies a duration, generated navigation uses 300 ms. **Instant** always uses zero duration. ![single-navigate-transition-animation.avif](animation_gifs/single-navigate-transition-animation.avif) ## Change global navigate transition -To change the default transition animation of your entire app, follow the steps below: +To change the default transition for Navigate To actions that use **Default**: + +1. Open **App Settings**, then expand **Routing & Deep Linking**. +2. Enable **Override Default Transition**. +3. Select **Transition Type**. +4. For a non-instant transition, set **Transition Duration (ms)**. Enabling the override initializes this value to 300 ms when no duration is already set. + +A transition explicitly selected on an individual Navigate To action takes precedence over the global override.
-
-

\ No newline at end of file +

diff --git a/docs/ff-concepts/animations/shaders.md b/docs/ff-concepts/animations/shaders.md index 6c0a24bf3..3f98fcb66 100644 --- a/docs/ff-concepts/animations/shaders.md +++ b/docs/ff-concepts/animations/shaders.md @@ -1,12 +1,17 @@ --- slug: /concepts/animations/shaders title: Shaders -description: Learn how to add visual effects using Shaders in your FlutterFlow app. -tags: [Animations, Concepts] +description: Configure ShaderFill and ShaderWrapper presets, animation modes, touch effects, actions, and custom Flutter fragment shaders in FlutterFlow. +tags: + - FlutterFlow + - Concepts sidebar_position: 5 -keywords: [FlutterFlow, Shaders, Concepts] +keywords: + - FlutterFlow + - Shaders + - Concepts +last_verified: 2026-09-02 --- - # Shaders Shaders let you add rich visual effects to your app, such as animated gradients, ripple distortions, dissolve transitions, and interactive touch effects. Instead of using static images or simple color backgrounds, shaders generate visuals in real time using the device’s graphics processor (GPU). This makes it possible to create smooth animations and procedural textures that feel dynamic and alive. @@ -16,9 +21,8 @@ Shaders let you add rich visual effects to your app, such as animated gradients, paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding height: 0, width: '100%'}}> - - -

- -**Install in Codex** - -1. Open the **Codex Desktop app**. -2. In the message box, type: `/sk` -3. Select **Skill Installer** from the skill suggestions list. -4. Ask Codex to install the Shadertoy skill directly from GitHub: - -``` -Install this skill https://github.com/FlutterFlow/shadertoy_to_flutter_skill -``` - -Codex will run the Skill Installer and install the skill into your local Codex folder. After installation finishes, restart Codex. - -
- -
-

+If your AI agent supports packaged `SKILL.md` instructions, install or add the repository using that agent's current supported mechanism. Product menus and commands change, so use the agent vendor's current documentation rather than relying on a copied UI sequence. If installation is unavailable, attach the repository files to the conversation and explicitly ask the agent to follow `SKILL.md`. -**Step 3: Using Skill** +**Step 2: Ask the agent to convert the shader** -You can use the skill with either a Shadertoy URL or a local .glsl file. +Provide either a Shadertoy URL or a local `.glsl` file. Explicitly ask the agent to use the `shadertoy-to-flutter` instructions and to report whether it produced a ShaderFill or ShaderWrapper shader. **Option A: Convert a Shadertoy URL** In the prompt, provide the Shadertoy URL and ask to convert into `.frag` file, for example: ``` -[invoke shadertoy-to-flutter skill] convert this Shadertoy shader into a Flutter .frag file: +Use the shadertoy-to-flutter skill to convert this Shadertoy shader into a +Flutter .frag file. Validate the result and list its FlutterFlow uniforms in +binding order: [shadertoy-url] ``` @@ -533,7 +420,9 @@ In the prompt, provide the Shadertoy URL and ask to convert into `.frag` file, f Open the Shadertoy shader you want to use, copy the shader code, and save it as a `.glsl` file. Then attach the file and use a prompt such as: ``` -[invoke shadertoy-to-flutter skill] convert this file into a Flutter .frag file +Use the shadertoy-to-flutter skill to convert the attached file into a Flutter +.frag file. Validate the result and list its FlutterFlow uniforms in binding +order. ```
-
+
::: @@ -84,9 +96,8 @@ When you set **Upload Type** to: paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding height: 0, width: '100%'}}> - -

\ No newline at end of file +

+ +## Related documentation + +See [Building Layout](/concepts/layouts) for a related FlutterFlow workflow. diff --git a/docs/ff-concepts/layout/responsive-widgets/conditional-builder-widget.md b/docs/ff-concepts/layout/responsive-widgets/conditional-builder-widget.md index 2b4bfb442..942d55883 100644 --- a/docs/ff-concepts/layout/responsive-widgets/conditional-builder-widget.md +++ b/docs/ff-concepts/layout/responsive-widgets/conditional-builder-widget.md @@ -1,14 +1,25 @@ --- slug: /concepts/layouts/conditional-builder title: ConditionalBuilder -description: Learn how to display different widgets based on certain conditions in your FlutterFlow app. -tags: [ConditionalBuilder, Concepts] +description: >- + Display one of several widget branches with ordered IF, ELSE IF, and ELSE + conditions in FlutterFlow. +tags: + - FlutterFlow + - Concepts sidebar_position: 1 -keywords: [FlutterFlow, ConditionalBuilder, Concepts] +keywords: + - FlutterFlow + - ConditionalBuilder + - Concepts + - show a different widget based on a condition +ai_queries: + - show a different widget based on a condition +last_verified: 2026-09-02 --- # ConditionalBuilder -The `ConditionalBuilder` widget allows you to dynamically display different widgets based on certain conditions (either [single](../../../resources/control-flow/functions/conditional-logic.md#single-condition) or [multiple](../../../resources/control-flow/functions/conditional-logic.md#multiple-conditions-andor)). Using this widget, you can define different conditions, each associated with a specific widget to be displayed when that condition is true. It's like having a switch that shows different things depending on what's happening in your app. +The **ConditionalBuilder** displays exactly one branch from an ordered **IF / ELSE IF / ELSE** chain. At runtime, FlutterFlow evaluates conditions from top to bottom, shows the child of the first true condition, and uses **ELSE** when none match. A nullable condition is treated as false. For example, displaying different charts based on user roles. For team members, an individual progress chart can be shown. Team leads can view the overall progress of the entire team, while project managers can see over project progress chart. Just like the below: @@ -18,15 +29,19 @@ For example, displaying different charts based on user roles. For team members, To add the `ConditionalBuilder` widget to your app: -1. Add the **ConditionalBuilder** widget (from the **Base Elements**) to where you want to display dynamic widgets. +1. Add a **ConditionalBuilder** where the dynamic content should appear. +2. In **Conditional Builder Properties**, set the **First Condition** by selecting **UNSET** and building a Boolean [condition](../../../resources/control-flow/functions/conditional-logic.md). +3. Next to **THEN**, select **Empty**, then add the single widget for that branch. +4. Select **+** to add an **ELSE IF** branch. Configure its condition and child. Drag the branch handle to change evaluation order. +5. Add the fallback child under **ELSE**. +6. Enable **Show in UI Builder** on one branch to preview it on the [canvas](../../../intro/ff-ui/canvas.md). This setting chooses the editor preview only; it does not change the generated runtime condition. -2. Move to the **Properties Panel** **>** **Conditional Builder Properties,** andUnder the **First Condition**, provide the **IF** [condition](../../../resources/control-flow/functions/conditional-logic.md) by clicking on **UNSET**. -3. Now, besides the **THEN**, click **Empty**. This will automatically select the **IF** widget in the widget tree. Inside that, add a widget that you want to display if this condition is true. -4. To add one more condition-based widget, click on the "+" button, add a condition for the **ELSE IF** section, and add a widget inside the **Else If** widget in the widget tree. -5. If none of the conditions are satisfied, add a default widget to display inside the **Else** widget. -6. Use the **Show In UI Builder** option to see that particular widget in the [canvas area](../../../intro/ff-ui/canvas.md). You can see only one widget at a time. +Every condition must be configured and every branch, including ELSE, must have a child before the project can generate successfully. Add or remove branches from **Conditional Builder Properties** rather than by dropping or deleting its structural branch nodes directly in the widget tree. -
+:::tip +Put the most specific or highest-priority condition first. Once a condition is true, later ELSE IF conditions are not evaluated for display. +::: + +
diff --git a/docs/ff-concepts/layout/responsive-widgets/flex-widget.md b/docs/ff-concepts/layout/responsive-widgets/flex-widget.md index f94af21ee..c3cca033a 100644 --- a/docs/ff-concepts/layout/responsive-widgets/flex-widget.md +++ b/docs/ff-concepts/layout/responsive-widgets/flex-widget.md @@ -1,15 +1,20 @@ --- slug: /concepts/layouts/flex title: Flex -description: Learn how to add the Flex widget in your FlutterFlow app. -tags: [Flex, Widget, Concepts] +description: Switch a multi-child FlutterFlow layout between horizontal and vertical axes with a Boolean condition using the Flex widget. +tags: + - FlutterFlow + - Concepts sidebar_position: 2 -keywords: [FlutterFlow, Wrap, Concepts] +keywords: + - FlutterFlow + - Flex + - Concepts +last_verified: 2026-09-02 --- - # Flex -The **Flex** widget can be used as an alternative to **Row** and **Column**. It allows you to dynamically set the layout axis (horizontal or vertical) based on specific conditions or logic. This is especially useful for creative responsive layouts - where child elements should be horizontal when the screen is wide, and vertical when the screen is narrow. +The **Flex** widget is a multi-child layout whose axis comes from the Boolean **Is Horizontal** property. When true it uses a horizontal axis like Row; when false it uses a vertical axis like Column. Bind the property to screen width or other logic when the layout should change at runtime. ![flex.png](imgs/flex.png) @@ -19,6 +24,8 @@ The **Flex** widget can be used as an alternative to **Row** and **Column**. It To use the Flex widget, add it from the **Layout Elements** section of the **Widget Palette**, then add child widgets inside it. From the properties panel, set a condition for the **Is Horizontal** property. When this condition evaluates to `True`, the items will be laid out horizontally. +The UI builder can evaluate **Is Horizontal** directly when its condition uses global properties such as screen width or height. More complex expressions involving variables or custom functions are evaluated correctly in generated code, but the builder may use the property's saved UI Builder Value to choose which axis to preview. + Consider an ecommerce app where recent orders are displayed vertically on mobile devices and switch to a horizontal layout on larger screens to make better use of the available space.
-

- diff --git a/docs/ff-concepts/localization-accessibility/accessibility.md b/docs/ff-concepts/localization-accessibility/accessibility.md index b5a4df096..cf0527875 100644 --- a/docs/ff-concepts/localization-accessibility/accessibility.md +++ b/docs/ff-concepts/localization-accessibility/accessibility.md @@ -1,10 +1,19 @@ --- slug: /concepts/accessibility title: Accessibility -tags: [Accessibility] -keywords: [FlutterFlow, Accessibility, Screen Reader Support, Semantic Labels] +tags: + - FlutterFlow + - Concepts +keywords: + - FlutterFlow + - Accessibility + - Screen Reader Support + - Semantic Labels + - make a FlutterFlow app accessible description: Learn how to make your app accessible to everyone. sidebar_position: 0 +ai_queries: + - make a FlutterFlow app accessible --- # Accessibility @@ -36,9 +45,8 @@ To add a semantic label for any widget, select the widget, move to the propertie paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding height: 0, width: '100%'}}> -

- + 2. Select the **Widget** (e.g., Button) from where you want to open the bottom sheet. 3. Select **Actions** from the Properties panel (the right menu), and click **+ Add Action**. -4. Search and select the **Bottom Sheet** (under *Widget/UI Interactions*) action. -5. To open the bottom sheet, select **Show**. -6. **Select Component** as the component you created for the bottom sheet. -7. (Optional) set the **Height** value. You should set the height if you want the bottom sheet to appear only up to some portion of the screen. -8. You can set the **Background** and **Barrier Color** for the bottom sheet. - +4. Search for **Bottom Sheet** under *Widget/UI Interactions*, then select **Show**. +5. Choose the component under **Display Component** and supply any required component parameters. +6. Optionally set **Height (Optional)** to override the component's inherent height. A bottom sheet cannot be taller than the presenting page. +7. Use **Background Color (Optional)** for the sheet surface and **Barrier Color (Optional)** for the overlay over the page behind it. + ![Set Background and Barrier color](imgs/bottom-sheet-background-color.png) - -9. You can also [pass parameters](../../resources/ui/components/creating-components.md#creating-a-component-parameter) to a bottom sheet component. -10. By default, this type of action blocks the following action (if any) from triggering while this action is in progress. (i.e., meaning the bottom sheet is present on the screen). However, in some cases, you might want to allow the next action (after this) to execute, for example, making an API call immediately after showing the bottom sheet. To do so, enable **Non Blocking** option. -11. By default, **Non Dismissble** option closes the bottom sheet when you click outside of it. To disable this behavior, enable this option. -12. With **Enable Drag** option, you can open and close the bottom sheet using a swipe gesture. -13. Optional: If you are returning any value from the bottom sheet, provide the **Action Output Variable Name**. The result will be stored in this variable. + +8. Leave **Non-Blocking** off when later actions must wait for the sheet to close or use its result. Enable **Non-Blocking** only when the flow should continue immediately after opening the sheet. +9. Enable **Non Dismissible** to prevent a tap on the barrier (scrim) from closing the sheet. +10. **Enable Drag** allows the user to drag the sheet and dismiss it by swiping downward. Turn it off as well as enabling **Non Dismissible** if the sheet must close only through an explicit action inside the component. +11. Enable **Use Safe Area** when the sheet's content should avoid operating-system intrusions at the top, left, and right edges. +12. If the component has a **Dismiss Bottom Sheet** action with **Has Value** enabled, set **Action Output Variable Name** on this opening action. Later actions can read the result under **Action Outputs**.
-
-

\ No newline at end of file +

diff --git a/docs/ff-concepts/navigation-routing/deep-dynamic-linking.md b/docs/ff-concepts/navigation-routing/deep-dynamic-linking.md index 36977566a..c423cee38 100644 --- a/docs/ff-concepts/navigation-routing/deep-dynamic-linking.md +++ b/docs/ff-concepts/navigation-routing/deep-dynamic-linking.md @@ -2,11 +2,19 @@ slug: /concepts/navigation/deep-dynamic-linking title: Deep & Dynamic Linking description: Learn how to implement deep and dynamic linking in your FlutterFlow app. -tags: [Deep Linking, Dynamic Linking, Concepts] +tags: + - FlutterFlow + - Concepts sidebar_position: 4 -keywords: [FlutterFlow, Deep Linking, Dynamic Linking, Concepts] +keywords: + - FlutterFlow + - Deep Linking + - Dynamic Linking + - Concepts + - configure deep links for a FlutterFlow app +ai_queries: + - configure deep links for a FlutterFlow app --- - # Deep & Dynamic Linking :::danger[Support for Dynamic Links] @@ -60,7 +68,7 @@ Let's build an example of sharing and opening a profile page using the deep link like the below:
- + Deep Link Example in FlutterFlow
Sharing and opening a deep link
@@ -110,7 +118,7 @@ To set the page URL: checkmark the **Requires Authentication** if your app works only after login.
- + Set Page Url in FlutterFlow
Setting page URL
@@ -135,7 +143,7 @@ To share the deep link of the current page: 5. Set the **Available Options** to **Link To Current Page** and click **Close**.
- + Sharing Deep Link in FlutterFlow
Sharing deep link
@@ -174,7 +182,7 @@ URL in the search bar, open the options menu and click on the **Open in app**. Here is how you do it:
- + Deep Link Example in FlutterFlow
Using Firefox mobile browser to open the deep link
@@ -199,7 +207,7 @@ from Firebase) to create dynamic links. Let’s walk through an example of sharing and opening a profile page using a dynamic link. The example will look like this:
- + Deep Link Example in FlutterFlow
Dynamic link example
@@ -230,7 +238,7 @@ To set up the domain name, follow the steps below: 4. If you chose Google Provided Domain, you could **Finish** the setup.
- > + Set Up Domain in FlutterFlow>
Setting up a domain for the dynamic link
@@ -258,7 +266,7 @@ To add the App Store and Team ID to the Firebase project: click **Save**. To know where is your Team ID, click on the question mark icon beside the label.
- + Add App Store Team Id in FlutterFlow
Adding App Store and Team ID to the Firebase project
@@ -274,7 +282,7 @@ To add the Associated Domain capability on App Store: 3. Checkmark the **Associated Domains** and click **Save**.
- + Add Capability in FlutterFlow
Adding Associated Domain capability to App Store
@@ -316,7 +324,7 @@ To set the page URL: However, checkmark the **Requires Authentication** if your app works only after login.
- + Set Page Url Dynamic Link in FlutterFlow
Setting page URL
@@ -348,7 +356,7 @@ To share the dynamic link of the page: 9. Set the **Available Options** to the **Current Page Link** and click **Close**.
- + Sharing Dynamic Link in FlutterFlow
Sharing dynamic link
@@ -366,7 +374,7 @@ into the search bar. Here is how you do it:
- + Dynamic Link Demo Testing in FlutterFlow
Testing Dynamic Link
@@ -377,7 +385,7 @@ page link with a discount code and share the profile page with its profile ID. P with the link can be used to retrieve the information required to display on the page.
- + Pasing Data in FlutterFlow
Passing profile id in the link
@@ -395,7 +403,7 @@ To pass custom data with the link, you need to have the following:
- ![img_6.png](imgs/img_6.png) + ![img_6.png](imgs/img_6.png)
Including a parameter in the route
@@ -413,9 +421,9 @@ With Branch, we can support robust deep linking inside FlutterFlow apps without Start by setting up your project in the [Branch Dashboard](https://dashboard.branch.io). Once you’ve created a project: -**1. Note down your Branch Key** +**1. Note down your Branch Key** -Once you create a project, the first thing you’ll need to do is note down your **Branch Key**. +Once you create a project, the first thing you’ll need to do is note down your **Branch Key**.
-
::: @@ -686,7 +691,7 @@ This library sets up everything you need for routing users into your app using B You can install the [Branch Deeplinking Library from the Marketplace](https://marketplace.flutterflow.io/item/oAco1HzQHxtOVE1ssTcC). Refer to the [Add Library Item](../../marketplace/adding-purchasing-item.md#add-library-item) instructions to see how to add it to your account. -### Branch Setup +### Branch Setup You’ll need three values from your Branch dashboard: @@ -724,9 +729,8 @@ Here’s a quick demo to show how to configure those values inside your library height: 0, width: '100%' }}> - + +When routing is enabled, **Navigate Back** can also expose **Navigate to Root Page on Failure**. Enable it when pressing Back with no previous route should return to the root page instead of doing nothing. + +## Related documentation + +See [Bottom Sheet](/concepts/navigation/bottom-sheet) for a related FlutterFlow workflow. diff --git a/docs/ff-concepts/navigation-routing/passing-data.md b/docs/ff-concepts/navigation-routing/passing-data.md index d449efc51..dc7654560 100644 --- a/docs/ff-concepts/navigation-routing/passing-data.md +++ b/docs/ff-concepts/navigation-routing/passing-data.md @@ -2,11 +2,20 @@ slug: /concepts/navigation/passing-data title: Passing Data description: Learn how to pass data between pages in FlutterFlow. -tags: [Passing Data, Navigation, Concepts] +last_verified: 2026-09-01 +tags: + - FlutterFlow + - Concepts sidebar_position: 2 -keywords: [FlutterFlow, Passing Data, Navigation, Concepts] +keywords: + - FlutterFlow + - Passing Data + - Navigation + - Concepts + - pass data or parameters between FlutterFlow pages +ai_queries: + - pass data or parameters between FlutterFlow pages --- - import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; @@ -28,7 +37,7 @@ To create a page parameter, follow the steps: height: 0, width: '100%' }}> - - \ No newline at end of file + + +## Related documentation + +See [Bottom Sheet](/concepts/navigation/bottom-sheet) for a related FlutterFlow workflow. diff --git a/docs/ff-concepts/navigation-routing/share-action.md b/docs/ff-concepts/navigation-routing/share-action.md index a19ab8bed..82b91e171 100644 --- a/docs/ff-concepts/navigation-routing/share-action.md +++ b/docs/ff-concepts/navigation-routing/share-action.md @@ -1,18 +1,26 @@ --- slug: /concepts/navigation/share-action -title: Share [Action] +title: 'Share [Action]' description: Learn how to use the Share Action in your FlutterFlow app to share content. -tags: [Share Action, Navigation, Concepts] +last_verified: 2026-09-01 +tags: + - FlutterFlow + - Concepts sidebar_position: 8 -keywords: [FlutterFlow, Share Action, Navigation, Concepts] +keywords: + - FlutterFlow + - Share Action + - Navigation + - Concepts --- - # Share [Action] The **Share Action** enables users to send text or URLs from your app using the native sharing capabilities of their device. This functionality allows users to share information through various applications installed on their devices, such as email, messaging apps, or social media platforms. +To configure it, add **Share** to an action flow and set **URL/Text Value** to a literal value or a compatible String or media-path variable. FlutterFlow passes that value to the iOS or Android native share sheet. + :::warning -It's important to note that the Share Action is designed for mobile platforms and is not supported in FlutterFlow's Run Mode or Preview Mode. To test this functionality, you need to [**run your app on an iOS or Android device or emulator**](../../testing-deployment-publishing/running-your-app/local-run.md). +The Share action is generated only for iOS and Android. It is not supported in Preview, Test, Run, or published web builds. Test it by [**running the app on an iOS or Android device or emulator**](../../testing-deployment-publishing/running-your-app/local-run.md). ::: -![share-action](imgs/share-action.avif) \ No newline at end of file +![share-action](imgs/share-action.avif) diff --git a/docs/ff-concepts/navigation-routing/special-page-navigation/imgs/setting-initial-tab-index.gif b/docs/ff-concepts/navigation-routing/special-page-navigation/imgs/setting-initial-tab-index.gif deleted file mode 100644 index b9b2a89cc..000000000 Binary files a/docs/ff-concepts/navigation-routing/special-page-navigation/imgs/setting-initial-tab-index.gif and /dev/null differ diff --git a/docs/ff-concepts/navigation-routing/special-page-navigation/imgs/setting-initial-tab-index.mp4 b/docs/ff-concepts/navigation-routing/special-page-navigation/imgs/setting-initial-tab-index.mp4 new file mode 100644 index 000000000..ca9e732db Binary files /dev/null and b/docs/ff-concepts/navigation-routing/special-page-navigation/imgs/setting-initial-tab-index.mp4 differ diff --git a/docs/ff-concepts/navigation-routing/special-page-navigation/overview.md b/docs/ff-concepts/navigation-routing/special-page-navigation/overview.md index ef9b94d5c..5a0a01f69 100644 --- a/docs/ff-concepts/navigation-routing/special-page-navigation/overview.md +++ b/docs/ff-concepts/navigation-routing/special-page-navigation/overview.md @@ -1,15 +1,20 @@ --- slug: /concepts/navigation/special-page-navigations -title: Overview +title: 'Overview: Special Page Navigation' description: Learn how to add Special Page Navigations in FlutterFlow. -tags: [Special Page Navigations, FlutterFlow, Navigation] +last_verified: 2026-09-01 +tags: + - FlutterFlow + - Concepts sidebar_position: 0 -keywords: [Special Page Navigations, FlutterFlow, Navigation] +keywords: + - Special Page Navigations + - FlutterFlow + - Navigation --- - # Overview -FlutterFlow provides special navigation widgets like Tab Bar, NavBar, and PageView for advanced navigation scenarios: +FlutterFlow provides navigation widgets for switching content without pushing a conventional full-page route: - **Tab Bar**: Used for navigating between different sections of your app with tabs, ideal for organizing content into categories. Learn more [here](tabbar). - **NavBar**: A bottom navigation bar that helps users switch between major sections of your app seamlessly. Learn more [here](../../../resources/ui/pages/page-elements.md#nav-bar). -- **PageView**: Allows for swipeable pages, perfect for creating onboarding screens or multi-step forms. Learn more [here](../../navigation-routing/special-page-navigation/pageview-widget.md). \ No newline at end of file +- **PageView**: Allows for swipeable pages, perfect for creating onboarding screens or multi-step forms. Learn more [here](../../navigation-routing/special-page-navigation/pageview-widget.md). diff --git a/docs/ff-concepts/navigation-routing/special-page-navigation/pageview-widget.md b/docs/ff-concepts/navigation-routing/special-page-navigation/pageview-widget.md index 70f203069..e0e7b5c28 100644 --- a/docs/ff-concepts/navigation-routing/special-page-navigation/pageview-widget.md +++ b/docs/ff-concepts/navigation-routing/special-page-navigation/pageview-widget.md @@ -1,12 +1,20 @@ --- slug: /concepts/navigation/pageview title: PageView -description: Learn how to use the PageView widget for creating swipeable pages, perfect for creating onboarding screens or multi-step forms. -tags: [PageView, FlutterFlow, UI, Widgets, Layout Elements] +description: >- + Learn how to use the PageView widget for creating swipeable pages, perfect for + creating onboarding screens or multi-step forms. +last_verified: 2026-09-01 +tags: + - FlutterFlow + - Concepts sidebar_position: 2 -keywords: [PageView, FlutterFlow, UI, Widgets] +keywords: + - PageView + - FlutterFlow + - UI + - Widgets --- - # PageView The PageView widget is used to create swipeable pages. In page view, you can add multiple child widgets, each of which is considered a page and can be scrolled horizontally or vertically. @@ -22,16 +30,15 @@ To add the PageView widget to your app: 2. By default, it adds three pages and shows the first one in the canvas. In the widget tree, it is represented as **PageView Page**. To see another page in the canvas, move to the **Properties Panel >** set the **Active Page** to the page you want to see. 3. To add a new page, move to the **Properties Panel > Active Page >** click **+ Add Page**. 4. To delete any page, select the **PageView Page** (which you want to delete) from the widget tree or the canvas area and press the **Delete** key on the keyboard. -5. By default, PageView Page contains an [Image](../../../resources/ui/widgets/basic-widgets/image.md) widget; however, you can customize it as per your requirement. For example, if you want to use the PageView widget to create an onboarding experience, you could wrap (`⌘` + B) the default image widget inside the Stack widget and then add some more widgets. +5. Each default PageView Page contains a Column placeholder. Replace or populate it with the layout you need. For an onboarding flow, for example, each page might contain an image, text, and controls arranged in a Column or Stack.
- -
\ No newline at end of file + diff --git a/docs/ff-concepts/navigation-routing/special-page-navigation/tabbar-widget.md b/docs/ff-concepts/navigation-routing/special-page-navigation/tabbar-widget.md index f5a289f97..755a292a9 100644 --- a/docs/ff-concepts/navigation-routing/special-page-navigation/tabbar-widget.md +++ b/docs/ff-concepts/navigation-routing/special-page-navigation/tabbar-widget.md @@ -1,12 +1,20 @@ --- slug: /concepts/navigation/tabbar title: TabBar -description: Learn how to use the TabBar widget in FlutterFlow to create a horizontal row of tabs for navigating different content views in your app. -tags: [TabBar, FlutterFlow, Navigation, Widgets] +description: >- + Learn how to use the TabBar widget in FlutterFlow to create a horizontal row + of tabs for navigating different content views in your app. +last_verified: 2026-09-01 +tags: + - FlutterFlow + - Concepts sidebar_position: 1 -keywords: [TabBar, FlutterFlow, Navigation, Widgets] +keywords: + - TabBar + - FlutterFlow + - Navigation + - Widgets --- - # TabBar The TabBar widget displays a horizontal row of tabs, allowing users to switch between different content views by tapping on the tabs. Each tab typically represents a different section or category of content. @@ -20,17 +28,17 @@ It can be used in various types of apps, such as news apps with different catego To add the TabBar widget to your app: 1. Add the **TabBar** widget from the **Layout Elements** tab. -2. By default, it adds three tabs to the page and shows the first one in the canvas. In the widget tree, it is represented as **Tab** and **TabBar Page**. To see another tab in the canvas, select the **TabBar** widget, move to the **Properties Panel,** and ****set the **Active Tab** to the one you want to see. +2. By default, it adds three tabs and shows the first one in the canvas. In the widget tree, each pair is represented as **Tab** and **TabBar Page**. To edit another tab, select the **TabBar** and set **Active Tab** in the Properties Panel. 3. To customize the Tab: 1. Select the **Tab >** Move to **Properties Panel**. 2. Use the **Text** property to change the label of the Tab. 3. You can also [add Icon](../../../resources/ui/widgets/basic-widgets/icons.md), align it horizontally, and set its margin. **Tip**: To only display Icon, remove the Text value. 4. Inside the **TabBar Page**, you can replace the existing **Text** widget with any widget of your choice. -5. To add a new tab, move to the **Properties Panel > Active Page >** click **+ Add Page**. +5. To add a tab, open **Properties Panel > Active Tab** and select **+ Add Tab**. :::tip - If you want to adjust the height of a TabBar Page, wrap a TabBar widget inside a container and then set the container’s height. -- You can find the currently selected tab index from *set from variable menu > widget state > TabBar Current Index*. +- You can read the zero-based current and previous indexes from **Set from Variable > Widget State > [TabBar name] Current Index** and **Previous Index**. :::
-
+ +## Related documentation + +See [Bottom Sheet](/concepts/navigation/bottom-sheet) for a related FlutterFlow workflow. diff --git a/docs/ff-concepts/notifications/notifications.md b/docs/ff-concepts/notifications/notifications.md index 27c244532..88416f844 100644 --- a/docs/ff-concepts/notifications/notifications.md +++ b/docs/ff-concepts/notifications/notifications.md @@ -1,12 +1,19 @@ --- slug: /concepts/notifications title: Notifications -description: Learn how to add notifications in FlutterFlow. -tags: [Notifications, Concepts] +description: >- + Notifications are alerts or messages that appear on a user's device outside + the normal UI flow of an app. +tags: + - FlutterFlow + - Concepts sidebar_position: 0 -keywords: [FlutterFlow, Notifications, Concepts] +keywords: + - FlutterFlow + - Notifications + - Concepts +last_verified: 2026-09-02 --- - # Notifications **Notifications** are alerts or messages that appear on a user's device outside the normal UI flow of an app. They can inform the user of time-sensitive or high-priority messages, events, or actions that require attention. Notifications may appear as banners, alerts, pop-ups, or lock-screen notifications, depending on user preferences and platform design guidelines. @@ -23,4 +30,4 @@ Generally, notifications can be divided into two main categories: **Local Notifi **Local Notifications** are scheduled directly on the device and do not require a server component. They are commonly used for time-based reminders or location-based triggers, such as a daily workout reminder at 7:00 AM. To implement local notifications in FlutterFlow, you can integrate the [flutter_local_notifications](https://pub.dev/packages/flutter_local_notifications) package using [custom actions](../../ff-concepts/adding-customization/custom-actions.md). -**[Push Notifications](push-notifications.md)**, on the other hand, are delivered from a remote server through a platform-specific push notification service. They are primarily used for real-time updates, such as chat messages, social media alerts, or news updates. In FlutterFlow, [Firebase Cloud Messaging](https://firebase.google.com/docs/cloud-messaging) (FCM) is used to handle push notifications, enabling seamless communication between your app and users. \ No newline at end of file +**[Push Notifications](push-notifications.md)** are delivered from a remote server through a platform-specific push service. They are commonly used for chat messages, alerts, and news updates. FlutterFlow's built-in push-notification flow uses [Firebase Cloud Messaging](https://firebase.google.com/docs/cloud-messaging) (FCM); using another push provider requires its own integration or custom code. diff --git a/docs/ff-concepts/notifications/one-signal.md b/docs/ff-concepts/notifications/one-signal.md index 3c36d6f5a..63183cd36 100644 --- a/docs/ff-concepts/notifications/one-signal.md +++ b/docs/ff-concepts/notifications/one-signal.md @@ -2,11 +2,19 @@ title: OneSignal slug: /concepts/notifications/one-signal sidebar_position: 2 -tags: [Actions, Alerts & Notifications, Integration] -keywords: [FlutterFlow, Actions, Alerts & Notifications, OneSignal] +tags: + - FlutterFlow + - Concepts +keywords: + - FlutterFlow + - Actions + - Alerts & Notifications + - OneSignal +description: >- + Integrating OneSignal lets you send emails and SMS (text messages) to your + users. +last_verified: 2026-09-02 --- - - # OneSignal Integrating OneSignal lets you send emails and SMS (text messages) to your users. This can help you @@ -16,11 +24,11 @@ be able to easily add users to or remove them from OneSignal's subscription list ![img.png](imgs/os-img.png) :::note[Prerequisites] -- Before you begin, make sure the project is on **Blaze plan** on Firebase. +- Before you begin, make sure the Firebase project is on the **Blaze** pay-as-you-go plan because FlutterFlow deploys Cloud Functions for this integration. Configure Firebase budgets and alerts before deploying. - [**Create an Account**](https://dashboard.onesignal.com/signup) on OneSignal ::: -## Initial Setup +## Initial Setup Here's a detailed, step-by-step guide to help you integrate OneSignal: ### Setup in OneSignal @@ -34,13 +42,13 @@ Here's a detailed, step-by-step guide to help you integrate OneSignal: settings by clicking **App > Settings > Platforms** and then select **Activate** for the services you want to use. - * If you're planning to use SMS, you'll need a [Twilio](https://twilio.com/) account and then - follow the steps from the official [SMS Quickstart documentation](https://documentation.onesignal.com/docs/twilio-setup#step-2-twilio-account-setup). + * If you're planning to use SMS, you'll need a [Twilio](https://twilio.com/) account and then + follow the steps from the official [SMS Quickstart documentation](https://documentation.onesignal.com/docs/en/sms-setup).
- + Activate SMS Service in FlutterFlow
SMS Configuration
- * For sending emails, configure your settings as per the guidelines provided in the OneSignal + * For sending emails, configure your settings as per the guidelines provided in the OneSignal [documentation](https://documentation.onesignal.com/docs/email-quickstart). ### Setup in FlutterFlow @@ -50,15 +58,15 @@ To enable OneSignal in FlutterFlow: 2. Switch on the **Enable OneSignal** toggle. 3. Gather your credentials: - - **App ID**: Find this in your OneSignal dashboard under **Settings > Keys & IDs > - OneSignal App ID**. - - **API Key**: Located in the same section as the App ID, under **Rest API Key**. - - **User Key**: Go to your user profile icon, then **Account & API Keys > User Auth Key**. + - **App ID**: Find this in your OneSignal app under **Settings > Keys & IDs**. The App ID is a public identifier. + - **API Key**: Create or copy an **App API Key** from the same page. + - **Organization API Key**: Open **Organizations > your organization > Keys & IDs** and create or copy an Organization API Key. - Click **Deploy**. + The App API Key and Organization API Key are secrets. Enter them only in the FlutterFlow integration fields, restrict them where possible, rotate them if exposed, and never place them in client-side custom code or a public repository. See OneSignal's [Keys & IDs](https://documentation.onesignal.com/docs/en/keys-and-ids) guide. +
-
+
@@ -74,8 +82,8 @@ com/embed/55a72de8e15e418581cc8b49fc108b12?sid=052ead4c-96e4-4e9a-95c5-40162eb0d There are two main actions you can utilize in OneSignal: -- **Add**: This lets you add users with their details like Email Address, Phone Number, and Tags. -- **Dismiss**: Use this to remove a user from the subscription list. +- **Add User**: Add the authenticated user with an email address, phone number, and optional tags. +- **Delete User**: Remove the user from the OneSignal integration. ### Adding OneSignal action @@ -83,34 +91,28 @@ To add a OneSignal action, such as adding a user, follow these steps: 1. Select the **Widget** (e.g., Button, etc.) on which you want to add the action. -2. Select **Actions** from the Properties Panel (the right menu). - -3. Search and select the **OneSignal** (under Integration) action. +2. Select **Actions** from the Properties Panel (the right menu). -4. Select the [Type](#types-of-onesignal-action) of the action. +3. Search for **OneSignal** under **Integrations**, then select **Add User** or **Delete User**. -5. To add a user, enable the subscription options you want. You can set the value directly or use +4. For **Add User**, enable the subscription options you want. You can set the value directly or use a variable. Remember, phone numbers should be in the [E.164 format](https://documentation.onesignal.com/docs/sms-faq#what-is-the-e164-format). -6. Optionally, add Tags for more personalized messaging. For example, you could tag users based on +5. Optionally, add Tags for more personalized messaging. For example, you could tag users based on their spending amount to target them with specific emails or SMS messages about their purchases.
-
+
-You can find out if the user was successfuly added to the subscription by navigating to **OneSignal dashboard > App > Audience > Subscriptions**. +You can confirm whether the user was successfully added by navigating to **OneSignal dashboard > App > Audience > Subscriptions**. ![img_2.png](imgs/os-img_2.png) :::info[OneSignal for Supabase Users] Currently, our OneSignal integration supports only Firebase authentication. If you want to use [**Supabase authentication**](../../ff-integrations/authentication/supabase-auth/initial-setup.md), you may need to use [**custom code**](../../ff-concepts/adding-customization/custom-code.md) to notify your users. ::: - - - diff --git a/docs/ff-concepts/notifications/push-notifications.md b/docs/ff-concepts/notifications/push-notifications.md index 554975a2e..94e696f77 100644 --- a/docs/ff-concepts/notifications/push-notifications.md +++ b/docs/ff-concepts/notifications/push-notifications.md @@ -2,11 +2,21 @@ title: Push Notifications slug: /concepts/notifications/push-notifications sidebar_position: 1 -tags: [Actions, Notifications, Integration] -keywords: [FlutterFlow, Actions, Notifications, Push Notifications] +tags: + - FlutterFlow + - Concepts +keywords: + - FlutterFlow + - Actions + - Notifications + - Push Notifications + - configure push notifications in FlutterFlow +description: >- + Push Notifications let you deliver time-sensitive, real-time messages to users + even when the app isn’t active. +ai_queries: + - configure push notifications in FlutterFlow --- - - # Push Notifications **Push Notifications** let you deliver time-sensitive, real-time messages to users even when the app isn’t active. These notifications rely on [**Firebase Cloud Messaging (FCM)**](https://firebase.google.com/docs/cloud-messaging) behind the scenes, which routes messages to both Android and iOS devices. When integrated correctly, you can use push notifications to: @@ -26,9 +36,9 @@ You can add and send push notifications manually or trigger them based on user a :::info[General Prerequisites] Before you begin, ensure that you: -- Complete all the steps in +- Complete all the steps in [**Firebase Setup**](../../ff-integrations/firebase/connect-to-firebase-setup.md). Note that, while setting up, make sure to follow step number 5 and 8 carefully from [**Allow FlutterFlow to Access Your Project**](../../ff-integrations/firebase/connect-to-firebase-setup.md#allow-flutterflow-to-access-your-project) section to properly add the **Cloud Functions Admin** role to **firebase@flutterflow.io** user. -- Upgrade your Firebase project to the [**Blaze plan**](https://firebase.google.com/pricing) to enable [**Cloud Functions**](https://firebase.google.com/docs/functions), which are required specifically for FlutterFlow’s push notification setup, such as retrieving the FCM token and sending notifications trigger from FlutterFlow. +- Upgrade your Firebase project to the [**Blaze plan**](https://firebase.google.com/pricing) to enable [**Cloud Functions**](https://firebase.google.com/docs/functions), which are required specifically for FlutterFlow’s push notification setup, such as retrieving the FCM token and sending notifications trigger from FlutterFlow. ::: :::info[iOS Prerequisites] @@ -49,7 +59,7 @@ To send push notifications to iOS devices, you must: To enable push notifications: -1. Navigate to the **Settings and Integrations > Push Notifications** and +1. Navigate to the **Settings and Integrations > Push Notifications** and **Enable Push Notifications**. 2. Now, click on the **Deploy** button. This will create and deploy the *Cloud Functions* in your Firebase project that are necessary for push notifications to work. 3. Optionally, you can enable **Allow Scheduling** to send push notifications at a later time. Once enabled, you can select **Scheduler Granularity**, which determines how precisely the notifications will be sent. You can choose the granularity based on how time-sensitive your notifications are; For example: @@ -93,9 +103,8 @@ After testing push notifications in the development environment, it's advisable paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding height: 0, width: '100%'}}> - +
::: FlutterFlow allows you to update the state of these widgets through actions exposed by the platform. For example, if you want to clear a TextField when the Send button is clicked on a form-like page, then in the Actions Flow, you can find relevant actions such as **Clear TextField**. This enables dynamic interaction and state management directly within the visual development environment. @@ -52,7 +64,7 @@ FlutterFlow allows you to update the state of these widgets through actions expo ## Action Triggers for Form Widgets FlutterFlow allows you to bind action triggers to widget states, such as calling an API on focus change of a textfield or changing the appearance of a button when a checkbox is checked. -**Most common Action Triggers exposed by form widgets:** +Available triggers vary by widget. Common form-widget triggers include: - **On Focus Change:** Triggered when a widget, such as a text field, gains or loses focus. For example, showing additional tips or validation messages when the user starts typing in a text field. @@ -64,12 +76,12 @@ For example, showing additional tips or validation messages when the user starts - **On Completed:** Triggered when a specific input is completed, such as entering a pincode. For example, automatically moving to the next step in a process after a complete and valid pincode is entered. -- **On Selected:** Triggered when an option is selected in widgets like choice chips, checkboxes, radio buttons, or sliders. For example, updating the UI or performing actions based on the selected option. +- **On Selected:** Triggered by supported selection widgets when an option is selected. Other controls, including sliders, may expose **On Change** instead. These triggers allow developers to create interactive and responsive applications by defining specific actions that occur in response to user interactions with form widgets. ![action-triggers-widget-state.png](imgs/action-triggers-widget-state.png) +## Related documentation - - +See [State Variables](/concepts/state-management) for a related FlutterFlow workflow. diff --git a/docs/ff-designer/collaboration/collaboration.md b/docs/ff-designer/collaboration/collaboration.md index 29e46b9be..59e75f261 100644 --- a/docs/ff-designer/collaboration/collaboration.md +++ b/docs/ff-designer/collaboration/collaboration.md @@ -1,12 +1,22 @@ --- slug: /designer/collaboration title: Collaboration -description: Work on the same design together — in real time, with comments and shared access. -tags: [Collaboration, FlutterFlow Designer, FlutterFlow, Design] +description: >- + Work on the same design together — in real time, with comments and shared + access. +tags: + - FlutterFlow + - Designer + - AI sidebar_position: 0 -keywords: [collaboration, share design, real-time editing, presence, comments, live cursors] +keywords: + - collaboration + - share design + - real-time editing + - presence + - comments + - live cursors --- - # Collaboration Collaboration lets multiple people work on the same design at once. Edits, cursors, and comments all stay in sync, so a team can explore and refine a design together without passing files back and forth. @@ -35,9 +45,8 @@ The owner manages who has access and can add, change a role, or remove collabora paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding height: 0, width: '100%'}}> -

+ +## Related documentation + +See [Prompting](/designer/prompting) for a related FlutterFlow workflow. diff --git a/docs/ff-designer/designing/prompting.md b/docs/ff-designer/designing/prompting.md index 099c63616..f027f6c97 100644 --- a/docs/ff-designer/designing/prompting.md +++ b/docs/ff-designer/designing/prompting.md @@ -1,12 +1,21 @@ --- slug: /designer/prompting title: Prompting -description: Generate your first app design from a prompt. Explore styles, attach reference images, and create a complete storyboard from a single description. -tags: [Prompting, FlutterFlow Designer, FlutterFlow, Design] +description: >- + Generate your first app design from a prompt. Explore styles, attach reference + images, and create a complete storyboard from a single description. +tags: + - FlutterFlow + - Designer + - AI sidebar_position: 0 -keywords: [flutterflow prompting, ai prompt design, generate app, explore styles, image attachments] +keywords: + - flutterflow prompting + - ai prompt design + - generate app + - explore styles + - image attachments --- - # Prompting Prompting is how you turn an idea into screens. Describe your app in the main prompt box, optionally attach a reference image, and the Designer generates a complete editable storyboard for you. @@ -37,8 +46,7 @@ Here's how you generate an initial screen design, refine, and export it: height: 0, width: '100%'}}>

+ +## Related documentation + +See [Export](/designer/export) for a related FlutterFlow workflow. diff --git a/docs/ff-designer/index.md b/docs/ff-designer/index.md index 7a60f7bc7..dce9494aa 100644 --- a/docs/ff-designer/index.md +++ b/docs/ff-designer/index.md @@ -1,14 +1,23 @@ --- slug: /designer title: Welcome -description: Discover FlutterFlow Designer—the fastest way to design apps. Explore its key features, understand how it works, and start designing your first app with ease. -tags: [FlutterFlow Designer, FlutterFlow, Design] +description: >- + Discover FlutterFlow Designer—the fastest way to design apps. Explore its key + features, understand how it works, and start designing your first app with + ease. +tags: + - FlutterFlow + - Designer + - AI sidebar_position: 0 -keywords: [flutterflow designer, ai app design, screen storyboard generation, ui design tool] +keywords: + - flutterflow designer + - ai app design + - screen storyboard generation + - ui design tool hide_title: true hide_table_of_contents: false --- - import InfoCard from '@site/src/components/InfoCard'; import InfoCards from '@site/src/components/InfoCards'; @@ -127,3 +136,7 @@ import InfoCards from '@site/src/components/InfoCards';

FlutterFlow Designer empowers both non-technical creators and development teams to move faster during early UX and UI exploration, then hand off straight to code. + +## Related documentation + +See [Slides](/designer/slides) for a related FlutterFlow workflow. diff --git a/docs/ff-designer/integrations/integrations.md b/docs/ff-designer/integrations/integrations.md index c47185b3b..9a546276a 100644 --- a/docs/ff-designer/integrations/integrations.md +++ b/docs/ff-designer/integrations/integrations.md @@ -1,12 +1,20 @@ --- slug: /designer/integrations title: Integrations -description: Connect FlutterFlow Designer with AI agents and developer tools to generate, edit, and update designs using natural language from your preferred environment. -tags: [Integrations, FlutterFlow Designer, FlutterFlow, Design] +description: >- + Connect FlutterFlow Designer with AI agents and developer tools to generate, + edit, and update designs using natural language from your preferred + environment. +tags: + - FlutterFlow + - Designer + - AI sidebar_position: 0 -keywords: [integrations, flutterflow designer, ai app design] +keywords: + - integrations + - flutterflow designer + - ai app design --- - # Integrations You can connect FlutterFlow Designer with external AI agents and developer tools. This enables you to generate, edit, and inspect designs directly from your preferred AI environment instead of working only inside the Designer UI. @@ -36,9 +44,8 @@ To add integrations, go to the **Integrations** section inside FlutterFlow Des paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding height: 0, width: '100%'}}> - +
@@ -26,24 +34,24 @@ com/embed/1e7a383897334f6da96c58639e7abcfc?sid=b8363cff-ccfb-4ade-98fc-22a2a587e Integrating [Gemini AI](https://gemini.google.com/app) into FlutterFlow unlocks Google's advanced AI capabilities right within your app. Follow this guide to integrate Gemini AI: -1. Visit [**Google AI Studio**.](https://aistudio.google.com/) and click on **Get API Key** > - **Create API key**. You can create an API key within a new Google Cloud project by selecting *Create API key in new project*, or choose an existing Google Cloud project. +1. Visit [**Google AI Studio**.](https://aistudio.google.com/) and click on **Get API Key** > + **Create API key**. You can create an API key within a new Google Cloud project by selecting *Create API key in new project*, or choose an existing Google Cloud project. -2. Once the API key is generated, copy it. +2. Once the API key is generated, copy it. Google is migrating Gemini API access from standard keys to authorization keys; follow the current key type and migration guidance shown in AI Studio. -:::tip -To secure your API keys, refer to the Best Practices guide: [Secure API Keys](../google-cloud/secure-keys.md) +:::danger[Protect the API key] +Treat the Gemini API key as a secret. Never hardcode it in a web or mobile client, commit it to source control, or place it in public app state. For production, route Gemini requests through a trusted server or use the recommended [AI Agent](ai-agents.md) integration. Restrict the key, configure billing alerts, and rotate it immediately if it is exposed. See [Secure API Keys](../google-cloud/secure-keys.md) and Google's [Gemini API key security guidance](https://ai.google.dev/gemini-api/docs/api-key). ::: -1. Go back to FlutterFlow and navigate to **Settings and Integrations > Integrations > Gemini**. +1. Go back to FlutterFlow and navigate to **Settings and Integrations > Integrations > Gemini**. -2. Toggle on the **Enable Gemini** option and paste the copied **API key** into the designated - field. +2. Toggle on the **Enable Gemini** option and paste the copied **API key** into the designated + field. -3. Now, you can add [Gemini actions](#gemini-action) at appropriate events +3. Now, you can add [Gemini actions](#gemini-action) at appropriate events within your app. -With these steps, you’re all set to enhance your FlutterFlow app with powerful AI features. +The legacy settings and action are available only in projects that had already enabled this integration. If they do not appear in your project, use [AI Agent](ai-agents.md). ## Gemini [Action] @@ -54,11 +62,11 @@ To add a Gemini Action, follow these steps: 2. Select **Actions** from the Properties Panel (the right menu), and click **Open**. This will open an **Action Flow Editor** in a new popup window. Click on the **+ Add Action**. -3. On the right side, search and select the **Gemini** (under *Integrations*) action. +3. On the right side, search and select the **Gemini** (under *Integrations*) action. 4. Set the [**Action Type**](#types-of-gemini-action). **Note** that If you set this type to *Text from Image*, you must provide the image as well. -5. Provide the **Text prompt** that will be used to generate the result from the Gemini AI model. For this example, we use this prompt: `When users upload a photo, you analyze the food in the photo and tell if it is healthy to eat`. +5. Provide the **Text prompt** that will be used to generate the result from the Gemini AI model. For this example, we use this prompt: `When users upload a photo, you analyze the food in the photo and tell if it is healthy to eat`. 6. Provide the **Action Output Variable Name** where the result of the generation will be stored. Later, you can access this variable from anywhere on the page. @@ -81,7 +89,7 @@ This action allows you to create natural language text based on the text prompts With this action, you can analyze the number of tokens in a given text prompt. This is particularly useful for applications that need to monitor or restrict the length of text inputs, ensuring that content stays within desired limits or quotas. -A token can be a word, but it can also be a part of a word or even punctuation. The division of text into tokens depends on the tokenization algorithm being used. For Gemini models, a token is equivalent to about 4 characters. 100 tokens are about 60-80 English words. +A token can be a word, part of a word, or punctuation. Tokenization varies by model and language, so use the **Count Tokens** action for an exact count instead of estimating from characters or words. **Example**: @@ -100,7 +108,3 @@ This action enables your app to analyze images and generate descriptive text abo + **Image Network URL**: You can provide the URL of the image hosted on the internet. If you upload an image to **Firebase** or **Supabase**, you can provide the image via ***Widget State > Uploaded File URL****.* + **Uploaded Image File**: You can also provide an image file directly [from your device](#) via ***Widget State > Uploaded Local File****.* * **Output**: *Action Output Variable Name* - "This is a pipe organ. It is a large musical instrument that is used in churches, concert halls, and other large buildings. The sound of a pipe organ is very powerful and can be used to create a wide variety of music." - - - - \ No newline at end of file diff --git a/docs/ff-integrations/analytics/google-analytics/google-analytics.md b/docs/ff-integrations/analytics/google-analytics/google-analytics.md index b24606851..874bc4168 100644 --- a/docs/ff-integrations/analytics/google-analytics/google-analytics.md +++ b/docs/ff-integrations/analytics/google-analytics/google-analytics.md @@ -1,12 +1,22 @@ --- slug: /integrations/google-analytics title: Google Analytics -description: Learn how to setup Google Analytics in FluterFlow -tags: [Google Analytics] +description: >- + Integrating Google Analytics into your FlutterFlow project enables you to + monitor user interactions, track app performance, and gain valuable insights + to enhance user experience. +tags: + - FlutterFlow + - Integrations + - Google Analytics sidebar_position: 1 -keywords: [Google Analytics, Firebase, Firebase Analytics, Track App Events] +keywords: + - Google Analytics + - Firebase + - Firebase Analytics + - Track App Events +last_verified: 2026-09-02 --- - # Google Analytics Integrating Google Analytics into your FlutterFlow project enables you to monitor user interactions, track app performance, and gain valuable insights to enhance user experience. Here's a comprehensive guide on setting up and utilizing Google Analytics within FlutterFlow. @@ -26,9 +36,8 @@ To enable Google Analytics in Firebase, open the [Firebase Console](https://cons paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding height: 0, width: '100%'}}> - ::: @@ -120,9 +133,7 @@ If you aren't planning to use **Google** or **Phone Sign-In**, you can skip thes ### Generate the SHA-1 key -An SHA-1 key (aka the 'Secure Hash Algorithm') is required if you want to use -Google Sign-in and Phone Sign-in. To learn more about the SHA-1 key, see -this [link](https://developers.google.com/android/guides/client-auth). +Register the certificate fingerprints for every Android signing identity that will run the app. Google sign-in requires the relevant SHA-1 fingerprint; phone authentication and related anti-abuse checks may also require SHA-256. Add debug fingerprints for local builds and the Google Play app-signing fingerprints for Play-distributed builds. See [Authenticating your client](https://developers.google.com/android/guides/client-auth). :::warning[Release Guidelines] While releasing the app, make sure to [**get the key from Play Console**](#getting-sha-keys-for-release-mode). @@ -155,13 +166,13 @@ While releasing the app, make sure to [**get the key from Play Console**](#getti
Mac/Linux
- ```keytool -list -v -alias androiddebugkey -keystore ~/.android/debug.keystore``` + ```keytool -list -v -alias androiddebugkey -keystore ~/.android/debug.keystore```
3. After being prompted for the key password, type 'android' and press 'Enter'. Note: For security reasons, you won't see the password as you type it. -4. Copy the SHA1 key. +4. Copy the SHA-1 and SHA-256 fingerprints you need for the provider and build type. #### Add the SHA-1 key in the Firebase Console @@ -170,19 +181,19 @@ While releasing the app, make sure to [**get the key from Play Console**](#getti 2. Select your Android App from the left side menu. 3. Find the SHA certificate fingerprints section and click on the Add fingerprint. -4. Enter the copied SHA-1 into the input box and click on Save. +4. Add each required SHA-1 or SHA-256 fingerprint and click **Save**. #### Getting SHA keys for release mode If you're releasing your app to the Play Store, you must add the SHA certificate fingerprints from the Play Console. -To get the keys for the release app, navigate to **Play Store Console > Your project > Release Setup > App Signing** and copy the **SHA-1** and **SHA-256** keys. +In Play Console, open your app's **App signing** page (the navigation label can vary as Play Console evolves) and copy the **SHA-1** and **SHA-256** fingerprints under **App signing key certificate**. Do not substitute the upload-key certificate: Google Play signs the APKs installed by users with the app-signing key. See Android's [Play App Signing documentation](https://developer.android.com/studio/publish/app-signing#app-signing-google-play). ![release-sha1-key](../imgs/release-sha1-key.avif) ### Regenerate config files -After adding the SHA-1 key you must re-generate the config files in FlutterFlow. +After adding or changing certificate fingerprints, regenerate the Firebase configuration files in FlutterFlow. To regenerate the config files: 1. Return to FlutterFlow. From the Navigation Menu, select **Settings & @@ -190,5 +201,3 @@ To regenerate the config files: 2. Click on the Regenerate Config Files. ![regerenate](../imgs/regerenate.png) - - diff --git a/docs/ff-integrations/authentication/firebase-auth/email-sign-in.md b/docs/ff-integrations/authentication/firebase-auth/email-sign-in.md index 0396dd98f..0983f4146 100644 --- a/docs/ff-integrations/authentication/firebase-auth/email-sign-in.md +++ b/docs/ff-integrations/authentication/firebase-auth/email-sign-in.md @@ -2,11 +2,18 @@ slug: /integrations/authentication/firebase/email-login title: Email Login description: Learn how to add Email Login in your FlutterFlow app. -tags: [Email Login, Authentication, Firebase] +tags: + - FlutterFlow + - Integrations + - Authentication sidebar_position: 3 -keywords: [FlutterFlow, Email Login, Authentication, Firebase] +keywords: + - FlutterFlow + - Email Login + - Authentication + - Firebase +last_verified: 2026-09-02 --- - # Email Login using Firebase :::info[Prerequisites] @@ -33,7 +40,7 @@ Before getting started with this section: In FlutterFlow, you can utilize the Page Templates feature to create a new authentication page that includes both a "Create Account" component and a "Log -In" component. +In" component. This setup aligns with Firebase's authentication process, which requires users to first create an account using their email and then allows them @@ -46,10 +53,9 @@ It's about establishing a user's credentials and granting them access for the first time. This action involves collecting necessary information such as email, password, and potentially other user-specific details like name or phone number. -The primary goal is to register and store new user data securely in your backend -or authentication service (like Firebase). This process typically includes steps -like validating the data format (e.g., email format), checking for unique -usernames or email addresses etc. +The primary goal is to register credentials with Firebase Authentication. Never +write passwords to Firestore, App State, logs, analytics, or your own user-profile +document. Firebase handles password storage and credential validation. To enable this in FlutterFlow, follow these steps: @@ -95,7 +101,7 @@ to [**Authentication Methods**](../authentication-methods.md) height: 0, width: '100%' }}> -
- +
@@ -154,6 +154,8 @@ allowFullScreen style={{ width: '100%', height: '600px' }}> clicking **+ CREATE CREDENTIALS**, selecting OAuth client ID and then select Application type to Web application. +For production, use domains you own or are authorized to use, configure accurate OAuth branding, publish a privacy policy and terms as applicable, and request only the minimum scopes. See Google's [OAuth 2.0 policies](https://developers.google.com/identity/protocols/oauth2/policies) and Firebase's [Google web sign-in guidance](https://firebase.google.com/docs/auth/web/google-signin). + ![add-app.gif](../imgs/add-app.gif) diff --git a/docs/ff-integrations/authentication/firebase-auth/jwt-token-login.md b/docs/ff-integrations/authentication/firebase-auth/jwt-token-login.md index ee8c9995e..421f9dcb4 100644 --- a/docs/ff-integrations/authentication/firebase-auth/jwt-token-login.md +++ b/docs/ff-integrations/authentication/firebase-auth/jwt-token-login.md @@ -2,18 +2,29 @@ slug: /integrations/authentication/firebase/jwt-auth title: JWT Token description: Learn how to implement JWT authentication in your FlutterFlow app. -tags: [JWT, Authentication, Firebase] +tags: + - FlutterFlow + - Integrations + - Authentication sidebar_position: 6 -keywords: [FlutterFlow, JWT, Authentication, Firebase] +keywords: + - FlutterFlow + - JWT + - Authentication + - Firebase +last_verified: 2026-09-02 --- - # JWT Token Authentication -[JWT](https://jwt.io/introduction) token sign-in allows you to log in and use the Firebase services such as Firebase Database and push notifications using the account created on your own server/backend. +Firebase custom-token sign-in lets your trusted backend authenticate a user in its own identity system and then issue a short-lived Firebase custom token. The app exchanges that one-time sign-in assertion with Firebase Authentication and receives the Firebase session used for Firestore, Storage, and other Firebase services. + +:::warning[Firebase custom token, not an arbitrary JWT] +The action requires a Firebase custom token with Firebase's required claims and signature. A JWT issued by Supabase, Okta, your normal API, or another identity provider cannot be passed through unchanged. Your trusted backend must verify the upstream identity and mint the Firebase custom token with the Firebase Admin SDK or an implementation that follows Firebase's specification exactly. +::: ![JWT-login-flow.avif](../imgs/JWT-login-flow.avif) -In JWT token authentication, you send login credentials, like email and password, to your server through an API endpoint. The server then creates a user account, generates a custom JWT token, and returns it to your app. This JWT token allows you to log in to Firebase and access its services. +The app sends credentials or an upstream identity assertion to your server over HTTPS. The server authenticates the request, chooses a stable Firebase UID, applies any approved custom claims, and returns a Firebase custom token. Never send a service-account key or signing credential to the app. :::info You can learn more about Firebase and JWT tokens [**here**](https://firebase.google.com/docs/auth/admin/create-custom-tokens). @@ -46,11 +57,9 @@ Adding JWT token authentication comprises the following steps: You must [create an API](../../../resources/control-flow/backend-logic/api/create-test-api-calls.md) endpoint on your server that accepts email/username and password. If the credentials are valid, it generates the JWT token and passes it back in response. -At your server, you can generate the JWT token either using the [Firebase Admin SDK](https://firebase.google.com/docs/auth/admin/create-custom-tokens#create_custom_tokens_using_the_firebase_admin_sdk) or a [third-party JWT library](https://firebase.google.com/docs/auth/admin/create-custom-tokens#create_custom_tokens_using_a_third-party_jwt_library). You can find the detailed instructions [here](https://firebase.google.com/docs/auth/admin/create-custom-tokens). +At your server, generate the custom token with the [Firebase Admin SDK](https://firebase.google.com/docs/auth/admin/create-custom-tokens#create_custom_tokens_using_the_firebase_admin_sdk) whenever possible. A third-party JWT library is appropriate only if your server implements Firebase's [documented custom-token format](https://firebase.google.com/docs/auth/admin/create-custom-tokens#create_custom_tokens_using_a_third-party_jwt_library), protects the signing key, and validates the caller before minting a token. -:::info -Alternatively, you can integrate Supabase authentication into your app and use the JWT token generated after [**account creation**](../supabase-auth/auth-actions.md#log-in-action). -::: +Rate-limit the login endpoint, avoid account-enumeration responses, do not log credentials or tokens, and authorize custom claims from server-side data rather than trusting values submitted by the client. The API endpoint should be similar to the following (Tip: Expand and see the '200 OK' section): @@ -77,8 +86,7 @@ The API endpoint should be similar to the following (Tip: Expand and see the '20 }, "token_type": "Bearer", "expires_in": 3600, - "jwt_token": "eyJraWQiOiItSE5TUmtwMWdXcG9QcC1wWVBmU1U4UW1fdng4Q0VwdzRSdTZTQU9WLThRIiwiYWxnIjoiUlMyNTYifQ.eyJ2ZXIiOjEsImp0aSI6IkFULi1PaG5EdWREUG9qWklsZjMtVDRVWHlTWW5ERElHQ3dYTUdQcXk1c1JUbjAub2FydGh3ZmxpbzhZOVZJbHc0eDYiLCJpc3MiOiJodHRwczovL2Rldi00NTc5MzEub2t0YS5jb20vb2F1dGgyL2F1c2hkNGM5NVF0RkhzZld0NHg2IiwiYXVkIjoiYXBpIiwiaWF0IjoxNjU5MDAyOTQ5LCJleHAiOjE2NTkwMDY1NDksImNpZCI6IjBvYWhkaGprdXRhR2NJSzJNNHg2IiwidWlkIjoiMDB1aGVuaDFwVkRNZzJ1ZXg0eDYiLCJzY3AiOlsib2ZmbGluZV9hY2Nlc3MiXSwiYXV0aF90aW1lIjoxNjU5MDAyOTQ5LCJzdWIiOiJhcGktdXNlcjRAaXd0Lm5ldCJ9.g2TyTQECo-HCSjn58Fmazki8DBCtCq2hkG6OGQOJgr0JUq3uHgj8ulojoBI5ckv3e3TcVGFg1x9KknSwgiZo0LxRpbAdbF27hfF8truExjEv7hGKoV_oAOaiD56be5K-HjYkp6j-b5S6gXe4N10T1NtovLI7L6MZvmqCL_26qzXni5hNkCjgRm8Rd6GnJwbjDLpV3snp51bVNYNqhoAhOPBqjmOErFQvO2Wmfkj8DuVXzsvRqm_xfb8-7Oosx5oGVMVR3liXW5NZsRWes4TXXwsEou3qCyVy5fAhzm7rKjIk1zWv9vm0IOWMFwHHYTgEc_LTYWMovWtkuBx4ia546Q", - "refresh_token": "dlIOQHHAmweyOrVkDlpNYpi1XM-DwX5Cgx70LoKIbTI" + "firebase_custom_token": "[FIREBASE_CUSTOM_TOKEN]" } ``` @@ -86,10 +94,6 @@ The API endpoint should be similar to the following (Tip: Expand and see the '20 In most cases, you would make the app content available right after creating a new account. Hence, you should also generate and return the JWT token on the success of create account API and use it to login into the Firebase. ::: -:::info -If you want to try the JWT token authentication without creating an API endpoint right now, you can [**generate the JWT token locally**](#create-a-jwt-token-locally) for testing. -::: - ### 2. Adding login page Let's add a sign-in page from the templates and choose the **Authenticate Solo Alt** from under the **Auth** tab. Tip: After adding, remove the other social sign-in buttons. @@ -112,7 +116,7 @@ Here are the step by step instructions: 7. Now, you must provide the actual JWT token. To set the token from an API response: 1. Click on the **UNSET** and select the **Action Outputs -> Action Output Variable Name** (that you specified in the API call section.) 2. Set the **API Response Options** to **JSON Body** and **Available Options** to **JSON Path**. - 3. Enter the **JSON Path** to locate the token in API response, such as `$.token,` and click **Confirm**. + 3. Enter the **JSON Path** that locates the token in your response, such as `$.firebase_custom_token`, and click **Confirm**. 8. (Optional) add the [snackbar action](../../../resources/ui/pages/page-elements.md#show-snackbar-action) to display the success message. 9. (Optional) Inside the **False** section, add the snackbar action to display the failure message. @@ -121,9 +125,8 @@ Here are the step by step instructions: paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding height: 0, width: '100%'}}> - - -

+Pass the temporary custom token directly from the test endpoint's action output to **Log In**. Do not persist it in App State, page state, logs, analytics, or a public decoder. Firebase custom tokens expire after a short period and are intended only for exchange with Firebase Authentication, not as bearer tokens for your own APIs. ## Accessing Firebase Database @@ -232,4 +175,4 @@ When such user reference is stored inside the Firestore documents, you can use t ![send-push-notification-to-users-created-via-JWT-token.png](../imgs/send-push-notification-to-users-created-via-JWT-token.png) -To learn more about how to use user references for sending push notifications, please check the [push notification](../../../ff-concepts/notifications/push-notifications.md) section. \ No newline at end of file +To learn more about how to use user references for sending push notifications, please check the [push notification](../../../ff-concepts/notifications/push-notifications.md) section. diff --git a/docs/ff-integrations/authentication/firebase-auth/phone-login.md b/docs/ff-integrations/authentication/firebase-auth/phone-login.md index dc600b521..2763ba613 100644 --- a/docs/ff-integrations/authentication/firebase-auth/phone-login.md +++ b/docs/ff-integrations/authentication/firebase-auth/phone-login.md @@ -2,23 +2,33 @@ slug: /integrations/authentication/firebase/phone title: Phone Login description: Learn how to add phone login in your FlutterFlow app. -tags: [Phone Login, Authentication, Firebase] +tags: + - FlutterFlow + - Integrations + - Authentication sidebar_position: 5 -keywords: [FlutterFlow, Phone Login, Authentication, Firebase] +keywords: + - FlutterFlow + - Phone Login + - Authentication + - Firebase +last_verified: 2026-09-02 --- - # Phone Login Phone login allows a user to sign in by sending an SMS message to the user's phone. The user login in using a one-time code contained in the SMS message. +:::warning[Security and consent] +Phone-number sign-in verifies possession of a number, not a person's real-world identity. Numbers can be recycled or transferred and SMS is vulnerable to SIM-swap and social-engineering attacks, so offer a stronger method for high-risk accounts or operations. Firebase sends and stores submitted phone numbers for spam and abuse prevention; obtain appropriate user consent, disclose possible SMS charges, review supported regions, and monitor SMS quotas and abuse. +::: +
-
- diff --git a/docs/ff-integrations/authentication/supabase-auth/email-supabase.md b/docs/ff-integrations/authentication/supabase-auth/email-supabase.md index f726abbe0..cfd7690fb 100644 --- a/docs/ff-integrations/authentication/supabase-auth/email-supabase.md +++ b/docs/ff-integrations/authentication/supabase-auth/email-supabase.md @@ -2,11 +2,17 @@ slug: /integrations/authentication/supabase/email title: Email Authentication description: Learn how to integrate Email Login of Supabase Auth into your FlutterFlow app. -tags: [Email Authentication, Authentication, Supabase] +tags: + - FlutterFlow + - Integrations + - Authentication sidebar_position: 2 -keywords: [FlutterFlow, Email Authentication, Authentication, Supabase] +keywords: + - FlutterFlow + - Email Authentication + - Authentication + - Supabase --- - # Email Authentication Supabase email authentication is a secure and easy way to allow users to sign up and log in to your application using their email and password. @@ -15,7 +21,7 @@ Supabase email authentication is a secure and easy way to allow users to sign up Before getting started with this section, ensure you have, 1. Completed all steps in the [**Supabase setup**](../../supabase/supabase-setup.md) -2. Completed [**Initial setup**](initial-setup.md) +2. Completed [**Initial setup**](initial-setup.md) required for authentication. ::: @@ -25,10 +31,9 @@ Before getting started with this section, ensure you have, Let's see how to add a Supabase email authentication by building an example that looks like this:
-
- - +
+ +
@@ -70,10 +75,9 @@ The first one creates an account in Supabase and adds an email and password in t Here's how it looks:
-
- - +
+ +
@@ -91,8 +95,8 @@ To verify that you have successfully added the email authentication, you can com
![img_5.png](img_5.png) - - + +
@@ -102,9 +106,4 @@ Now that you have successfully added the Supabase email authentication in your a Here's an example of filtering the to-do list based on the logged-in user using the **Set Variable menu > Authenticated User > User ID** property. -
- - - - +
diff --git a/docs/ff-integrations/authentication/supabase-auth/google-supabase.md b/docs/ff-integrations/authentication/supabase-auth/google-supabase.md index d91ddc118..b936f99ee 100644 --- a/docs/ff-integrations/authentication/supabase-auth/google-supabase.md +++ b/docs/ff-integrations/authentication/supabase-auth/google-supabase.md @@ -1,10 +1,20 @@ --- slug: /integrations/authentication/supabase/google title: Google Login -description: Learn how to integrate Google Login of Supabase Auth into your FlutterFlow app. -tags: [Google Authentication, Authentication, Supabase] +description: >- + Learn how to integrate Google Login of Supabase Auth into your FlutterFlow + app. +tags: + - FlutterFlow + - Integrations + - Authentication sidebar_position: 3 -keywords: [FlutterFlow, Google Authentication, Authentication, Supabase] +keywords: + - FlutterFlow + - Google Authentication + - Authentication + - Supabase +last_verified: 2026-09-02 --- # Google Login @@ -14,7 +24,7 @@ Google Authentication with Supabase offers a secure and convenient method for us Before getting started with this section, ensure you have, 1. Completed all steps in the [**Supabase setup**](../../supabase/supabase-setup.md) -2. Completed [**Initial setup**](initial-setup.md) +2. Completed [**Initial setup**](initial-setup.md) required for authentication. ::: @@ -27,9 +37,8 @@ Let's see how to add a Supabase Google authentication by building an example tha paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding height: 0, width: '100%'}}> - - - +
+ +
:::note -The "users" table in auth (protected) schema is a private table that Supabase uses to store auth-related sensitive information such as email, encrypted pass, and confirmation token. +The `auth.users` table is managed by Supabase and is not exposed through the auto-generated API. Do not copy credential fields into your public profile table. Follow [Supabase user-management guidance](https://supabase.com/docs/guides/auth/managing-user-data) when designing a profile table or signup trigger. ![img.png](img.png) ::: @@ -47,11 +58,10 @@ To enable authentication in FlutterFlow: 1. Open your FlutterFlow project. -2. Navigate to the Setting and Integrations () from the Navigation Menu > App Settings > - Authentication. +2. Navigate to **Settings and Integrations > App Settings > Authentication**. 3. Turn on the **Enable Authentication** toggle and select **Authentication Type** to **Supabase**. 4. To ensure that your users are directed to the appropriate pages based on their login status, you must set the [initial pages](../../../resources/projects/settings/general-settings.md#initial-page). -![img_1.png](img_1.png) \ No newline at end of file +![img_1.png](img_1.png) diff --git a/docs/ff-integrations/authentication/supabase-auth/supabase-apple-auth.md b/docs/ff-integrations/authentication/supabase-auth/supabase-apple-auth.md index 918692329..e5af5cf89 100644 --- a/docs/ff-integrations/authentication/supabase-auth/supabase-apple-auth.md +++ b/docs/ff-integrations/authentication/supabase-auth/supabase-apple-auth.md @@ -1,12 +1,19 @@ --- slug: /integrations/authentication/supabase/apple -title: Apple Login +title: 'Apple Login: Supabase Auth' description: Learn how to integrate Apple Login of Supabase Auth into your FlutterFlow app. -tags: [Apple Authentication, Authentication, Supabase] +tags: + - FlutterFlow + - Integrations + - Authentication sidebar_position: 4 -keywords: [FlutterFlow, Apple Authentication, Authentication, Supabase] +keywords: + - FlutterFlow + - Apple Authentication + - Authentication + - Supabase +last_verified: 2026-09-02 --- - # Apple Login Adding Apple Sign-In with Supabase offers a convenient, secure, and privacy-friendly way for users to sign up or log in to your app using their Apple ID. @@ -18,9 +25,8 @@ This guide will walk you through the steps necessary to integrate Apple login wi paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding height: 0, width: '100%'}}> - +
### Define Schema (Creating Fields) -A document represents a single item or entity, such as a user, post, animal, etc. To add data inside the document, you must define the document schema by creating Fields. Creating Fields helps you know what kind of data a document can contain. +A document represents a single item or entity, such as a user, post, or animal. Firestore itself permits documents in the same collection to contain different fields. FlutterFlow's collection schema describes the fields and types the builder and generated app expect, so keep stored documents compatible with that schema. Although you can add more fields later on, it's always a good idea to add fields from the start. :::caution -Field names cannot be changed, so ensure that you have used the correct Field names. +FlutterFlow does not provide an in-place field rename. Choose field names carefully. Changing a field name later requires adding the replacement field, migrating existing documents, updating every reference, and then removing the old field only after the migration is complete. +::: + +:::tip[Plan before production] +Decide which fields are required, how documents relate, and which queries the app needs. Then configure and test [Firestore Security Rules](firestore-rules.md) and deploy any required indexes. A FlutterFlow schema is not an authorization boundary, and every read can affect Firestore usage and cost. ::: To define the schema (create fields) for the document: @@ -59,7 +72,7 @@ To define the schema (create fields) for the document: 1. Select your collection from the list on the left side. 2. If you haven't added any fields yet: - 1. You can choose from the template collections that have common fields needed in most + 1. You can choose from the template collections that have common fields needed in most applications. This will auto-add all the fields. 5. Click on **Start from scratch** to define your own schema. 8. Or, use [AI Gen Schema](#create-schema-using-ai-gen). @@ -75,13 +88,12 @@ To define the schema (create fields) for the document: You can also use *Tab* and *Enter* keys to navigate quickly while creating fields. ::: -
+
### Create schema using AI Gen -With **AI Gen Schema**, you can automatically generate a schema for your Firebase collection from a +With **AI Gen Schema**, you can automatically generate a schema for your Firebase collection from a simple prompt. :::tip[To get better results...] @@ -96,8 +108,7 @@ Example prompts: - Create a collection for art exhibits, visitor reviews, and ticket bookings. - Generate a collection for online courses, student feedback, and enrollment records. -
+
--- @@ -105,3 +116,4 @@ com/embed/f3a3c7ad69194342926f83036f07b243?sid=e4ed8f7c-6465-42c3-a46e-0e80a4d1e :::note To learn more about custom data types within FlutterFlow, [check this doc](../../../resources/data-representation/data-types#built-in-data-types) +::: diff --git a/docs/ff-integrations/database/cloud-firestore/creating-subcollections.md b/docs/ff-integrations/database/cloud-firestore/creating-subcollections.md index e52f6519e..875f9cf8b 100644 --- a/docs/ff-integrations/database/cloud-firestore/creating-subcollections.md +++ b/docs/ff-integrations/database/cloud-firestore/creating-subcollections.md @@ -1,18 +1,28 @@ --- slug: /integrations/database/cloud-firestore/creating-subcollections title: Creating Subcollections -description: Learn how to create subcollections in Firestore for your FlutterFlow app, including organizing documents within subcollections. -tags: [Firestore, Database, Subcollections, Cloud Firestore] +description: >- + Learn how to create subcollections in Firestore for your FlutterFlow app, + including organizing documents within subcollections. +tags: + - FlutterFlow + - Integrations + - Database sidebar_position: 4 -keywords: [FlutterFlow, Firestore, Database, Subcollections, Cloud Firestore] +keywords: + - FlutterFlow + - Firestore + - Database + - Subcollections + - Cloud Firestore +last_verified: 2026-09-02 --- - # Creating Subcollections -[Collections](creating-collections.md) that are created inside the document are called subcollections. For example, +[Collections](creating-collections.md) that are created inside the document are called subcollections. For example, you could have a 'comments' subcollection inside the 'posts' collection to store a post's comments. -Subcollection is best when you have several queries/filters or search on a collection based on the other collection. For example, loading or searching the comments of a specific post. (i.e., show all comments of a post with more likes.) +A subcollection is useful when child records naturally belong to a parent document, such as comments for one post. Use a top-level collection with a parent reference instead when most queries need to search across all parents. :::caution[Feature Completion] At this time, FlutterFlow supports one level of nesting (e.g., collection -> subcollection). Second-level nesting is not currently supported ( e.g., collection -> subcollection 1 -> subcollection 2.) @@ -38,6 +48,10 @@ In this section, you'll learn to work with subcollections by building an example ::: +:::warning[Deletion and collection-group queries] +Deleting a parent document does **not** delete its subcollections. Implement and test an explicit cleanup process when child data must be removed. A collection-group query searches every subcollection with the same collection ID and can require a collection-group index and compatible version 2 security rules. +::: + Before we begin, we need to identify the collections and define the database structure. So looking at the requirements, it's very clear that we'll need two collections. One for storing chat room details and another for storing its messages. And we need to display the messages only for a specific chat room. So, having the message collection as a subcollection of the chat rooms seems to be a good option. Here's what the database structure looks like: @@ -54,7 +68,7 @@ Building the chat room example comprises the following steps: ### 1. Creating a collection -[**Create the collection**](creating-collections.md) called *chat_rooms*. This will be used to hold the chat room +[**Create the collection**](creating-collections.md) called *chat_rooms*. This will be used to hold the chat room details. While defining the schema for *chat_rooms* collection, add the fields to display its name, i.e., *chat_room_name.* @@ -71,12 +85,11 @@ To create the subcollection: 4. **Turn on** the **Is Subcollection** toggle. 5. The dropdown list with existing collections will appear. Click on the **Unset** and select the parent collection, *chat_rooms* in this case. 6. Click **Create** Button. -7. Next, [define the document schema](creating-collections.md#define-schema-creating-fields). While defining the schema for - the 'messages' +7. Next, [define the document schema](creating-collections.md#define-schema-creating-fields). While defining the schema for + the 'messages' subcollection, add the fields such as *message* (to store the message body) and *from* (to store the sender name). -
+

@@ -85,8 +98,7 @@ com/embed/242ba30097fd4a3986844489027185d9?sid=1c4e4ba9-dc46-4959-8b3f-5463ab004 Add some default chat room details using [Firestore Content Manager](firebase-content-manager.md). -
+

@@ -97,16 +109,15 @@ The first page shows the chat room listing, and when you tap, it opens the new p The steps to build the chat room page are as follows: -1. Query the **chat_rooms** collection and display the chat room names in a ListTile (inside +1. Query the **chat_rooms** collection and display the chat room names in a ListTile (inside ListView). -2. Add the **[Navigate To](../../../ff-concepts/navigation-routing/nav-overview.md#navigation-actions)** action **on - Tap** of the **ListTile** and open the messages page. **Note**: While navigating, pass the - chat room record to the next page. Learn how to +2. Add the **[Navigate To](../../../ff-concepts/navigation-routing/nav-overview.md#navigation-actions)** action **on + Tap** of the **ListTile** and open the messages page. **Note**: While navigating, pass the + chat room record to the next page. Learn how to [pass data to the next page](../../../ff-concepts/navigation-routing/passing-data.md). . -
+

@@ -121,25 +132,19 @@ The steps to build the chat room page are as follows: ![img_24.png](img_24.png) -2. On the ListView, query a subcollection as you would query any - other collection; except +2. On the ListView, query a subcollection as you would query any + other collection; except for the subcollection, you must provide its parent collection reference (i.e., chat_rooms reference in this case). This way, you'll only see messages from that specific chat room. -
+

-3. On tap of 'Send' button, add the [create document](firestore-actions.md#create-document-action) - action for - `messages` collection and provide current `chat_rooms` reference. Also, provide the message +3. On tap of 'Send' button, add the [create document](firestore-actions.md#create-document-action) + action for + `messages` collection and provide current `chat_rooms` reference. Also, provide the message to add via **From Variable > Widget State > [TextFieldName]**. -
+

- - - - diff --git a/docs/ff-integrations/database/cloud-firestore/firebase-content-manager.md b/docs/ff-integrations/database/cloud-firestore/firebase-content-manager.md index 50b445ad3..8973eed9a 100644 --- a/docs/ff-integrations/database/cloud-firestore/firebase-content-manager.md +++ b/docs/ff-integrations/database/cloud-firestore/firebase-content-manager.md @@ -1,17 +1,31 @@ --- slug: /integrations/database/cloud-firestore/firestore-content-manager title: Firestore Content Manager -description: Learn how to use the Firestore Content Manager in your FlutterFlow app to manage Firestore data efficiently. -tags: [Firestore, Database, Content Manager, Cloud Firestore] +description: >- + Learn how to use the Firestore Content Manager in your FlutterFlow app to + manage Firestore data efficiently. +tags: + - FlutterFlow + - Integrations + - Database sidebar_position: 5 -keywords: [FlutterFlow, Firestore, Database, Content Manager, Cloud Firestore] +keywords: + - FlutterFlow + - Firestore + - Database + - Content Manager + - Cloud Firestore +last_verified: 2026-09-02 --- - # Firestore Content Manager -The Firestore Content Manager provides an easy way to visually create, edit, and add documents +The Firestore Content Manager provides an easy way to visually create, edit, and add documents to your [**Firestore database**](getting-started.md). +:::warning[Production data] +Content Manager changes live Firestore documents. Confirm that you selected the intended Firebase project and database, restrict project access, and back up important data before bulk imports or destructive edits. The schema shown in FlutterFlow is a typing aid, not a substitute for security rules or data validation. +::: + :::info Subcollections are not supported in Content Manager at this time. ::: @@ -23,8 +37,8 @@ Before getting started with this section, ensure you: 1. Become familiar with [**Structuring the Firebase Database**](getting-started.md#structuring-the-database). 2. Completed all steps in the [**Firebase Setup**](../../firebase/connect-to-firebase-setup.md). 3. Create a [**Collection**](creating-collections.md). -4. [**Defined the Fields**](creating-collections.md#define-schema-creating-fields) for the collection. Only fields defined in - your Firebase schema are +4. [**Defined the Fields**](creating-collections.md#define-schema-creating-fields) for the collection. Only fields defined in + your Firebase schema are shown in the Firebase Content Manager. ::: @@ -39,22 +53,21 @@ Before you add a new document to the collection, make sure you have some Fields To add a document: -1. Head to the **Firestore** (left side Navigation Menu) and click **Manage Content**. This will +1. Head to the **Firestore** (left side Navigation Menu) and click **Manage Content**. This will open up a new browser window. 2. Select the **Collection** to which you want to add a document and then select + **Add Document.** A popup will appear. 3. Enter the information for the record and click **Add Document**. :::caution -If you get this error "**Could not create an account as firebase@flutterflow.io to your Firebase -project**", just enable the '[**Email Sign-In**](../../authentication/firebase-auth/email-sign-in.md)' in your -Firebase +If you get this error "**Could not create an account as firebase@flutterflow.io to your Firebase +project**", just enable the '[**Email Sign-In**](../../authentication/firebase-auth/email-sign-in.md)' in your +Firebase project. ![img_13.png](img_13.png) ::: -
+
@@ -68,6 +81,8 @@ To successfully upload the data: * Ensure you have header rows in your CSV file. The header should contain the exact name of the fields you have in your collection. * If you are uploading lat-long data, make sure you format it like (lat, lng) or [lat,lng]. * Dates must be in a format like YYYY-MM-DD HH:MM:SS, where hours should be in 24hrs format (e.g., 2022-11-07 13:05:32). +* Test the import with a small row count first. Validate types, references, timestamps, list values, and missing fields before importing the complete file. +* Keep a recoverable copy of the source data. A successful import can create many live documents and is not an automatic migration rollback. ::: To better understand, here is the sample places collection and CSV file: @@ -83,7 +98,7 @@ Zoo,"(40.85452267684994, -73.8774290321384)",2022-11-04 03:05:54 ``` Here's how you upload the CSV file: -1. Select the **Collection** and click the **Upload CSV** button (see top right side). A popup +1. Select the **Collection** and click the **Upload CSV** button (see top right side). A popup will open. 2. Click **Select File** and upload your CSV file. 3. Now, you can choose the **Separator Type** and enter the **Number of Rows to Upload**. If you leave this empty, all records will be imported. @@ -97,15 +112,13 @@ will open.
Formatting issue
-
+

-If your CSV file contains additional fields, you'll go through a quick *field import process* that will add the new fields with their data in your collection. +If your CSV file contains additional fields, you'll go through a *field import process* that can add those fields to the FlutterFlow schema and imported documents. Review every inferred field name and type before confirming; inconsistent types can break queries or generated field access later. -
+
@@ -135,8 +148,7 @@ To add a document reference: 1. Find the **Field** that accepts document reference and **paste** it 2. Click **Add Document**. -
+
@@ -160,8 +172,7 @@ Select the **Collection** you would like to add a document to and then select + To modify the given Date Time, click on the Date Time Field again to open the Date Picker dialog. ::: -
+
@@ -181,8 +192,7 @@ Select the **Collection** you would like to add a document to and then select + * Click on the icon to find the place and get the LatLng. 2. Click **Add Document**. -
+
@@ -210,14 +220,13 @@ To add data to a custom data type field: Select the **Collection** you would like to add a document to and then select + **Add Document**.A popup will appear. 1. Find the **Field** that accepts a custom data type. -2. Select **Tap to Set Fields (Unset)** or **Tap to Edit Fields** (based on whether you are +2. Select **Tap to Set Fields (Unset)** or **Tap to Edit Fields** (based on whether you are creating or updating the document). This will open a new popup. 3. Enter the values for the fields of the custom data type. 4. Select **Save Data**. 5. Click **Add Document**. -
+
@@ -228,13 +237,12 @@ com/embed/f16b8393e86342848b5c2d361f184956?sid=05f7a626-6de1-49cb-a730-73ee74e84 To update a document: -1. Select the **pencil icon** in the row of the Document you want to update**.** You can also open +1. Select the **pencil icon** in the row of the Document you want to update**.** You can also open the record by long-pressing any field in the Document (excluding the ID). 2. A popup will appear. Update the document as needed and then select **Update Document.** 3. You will now see the updated information displayed in your collection. -
+
--- @@ -258,7 +266,7 @@ To fix this issue, you must [**deploy the Firestore Rules**](firestore-rules.md#
Getting the error "Could not create an account as firebase@flutterflow.io to your Firebase project. -If you encounter such an issue, you just need to enable the -[**Email Sign-In**](../../authentication/firebase-auth/email-sign-in.md) in your +If you encounter such an issue, you just need to enable the +[**Email Sign-In**](../../authentication/firebase-auth/email-sign-in.md) in your Firebase project.
diff --git a/docs/ff-integrations/database/cloud-firestore/firestore-actions.md b/docs/ff-integrations/database/cloud-firestore/firestore-actions.md index faef5d54d..943c50e7a 100644 --- a/docs/ff-integrations/database/cloud-firestore/firestore-actions.md +++ b/docs/ff-integrations/database/cloud-firestore/firestore-actions.md @@ -1,17 +1,31 @@ --- slug: /integrations/database/cloud-firestore/firestore-actions title: Firestore Actions -description: Learn about Firestore actions in your FlutterFlow app, including how to perform various database operations. -tags: [Firestore, Database, Actions, Cloud Firestore] +description: >- + Learn about Firestore actions in your FlutterFlow app, including how to + perform various database operations. +tags: + - FlutterFlow + - Integrations + - Database sidebar_position: 6 -keywords: [FlutterFlow, Firestore, Database, Actions, Cloud Firestore] +keywords: + - FlutterFlow + - Firestore + - Database + - Actions + - Cloud Firestore toc_max_heading_level: 5 +last_verified: 2026-09-02 --- - # Firestore Actions The Firestore action allows you to create, update, or delete a record from a Firestore Collection. +:::warning[Security comes from rules] +Every mobile or web client request is evaluated by deployed [Firestore Security Rules](firestore-rules.md). Hiding an action in the UI, filtering a query, or defining a FlutterFlow schema does not authorize access. Test allowed and denied reads and writes before publishing. +::: + :::info[Prerequisites] - Get to know how to [**structure the Firebase Database**](getting-started.md#structuring-the-database). @@ -24,14 +38,14 @@ The Firestore action allows you to create, update, or delete a record from a Fir Following are the types of Firestore database action: -1. [**Create Document**](#create-document-action)**:** Creates a new record inside the specified +1. [**Create Document**](#create-document-action)**:** Creates a new record inside the specified Firestore Collection. 2. [**Read Document**](#read-document-action): Fetches document data using a reference. -3. [**Update Document**](#update-document-action)**:** Updates the specified field value of the +3. [**Update Document**](#update-document-action)**:** Updates the specified field value of the existing document. -4. [**Delete Document**](#delete-document-action)**:** Deletes records inside the specified +4. [**Delete Document**](#delete-document-action)**:** Deletes records inside the specified Firestore Collection. -5. [**Query Collection**](#query-collection-action): Retrieves record(s) from the Firstore +5. [**Query Collection**](#query-collection-action): Retrieves record(s) from the Firstore collection. ### Create Document [Action] @@ -50,8 +64,9 @@ Go to your project page on FlutterFlow and follow the steps below to define the 8. Similarly, add the field for the other UI elements. 9. By default, documents are added with an auto-generated ID. However, if you prefer to use your own ID for the document, you can enable the **Custom ID** toggle. -
+Custom IDs must be unique within the collection. Creating a document at an existing custom ID can overwrite or fail according to the generated operation and deployed rules, so validate the ID and prevent accidental reuse. + +
@@ -67,8 +82,7 @@ Here are some more use cases where you may find this action helpful: Let's see how to add this action with an example that fetches and displays the details of users who've reviewed a travel destination. Here's how it looks: -
+

@@ -86,18 +100,18 @@ Follow the steps below to define this action to any widget: 5. Now, **Select Reference to Read** data from. 6. Provide the **Action Output Variable Name**. This will be used to store the document data. +Handle the case where the reference does not exist or the read is denied. Do not assume the action output is populated until the action completes successfully. +

-
+

-7. Now, you can use the *Action Output Variable Name* provided in the previous step to fetch the +7. Now, you can use the *Action Output Variable Name* provided in the previous step to fetch the details. For example, to display data on Text widget, select the **Text widget > Properties Panel > Text > Set Variable menu > ***[action_output_variable_name]*** > select the field** you want to display. -
+
@@ -117,8 +131,7 @@ Go to your project page on FlutterFlow and follow the steps below to define the 2. Click on **UNSET** and select **Widget State > Name** of the TextField. 8. Similarly, add the field for the other UI elements. -
+
@@ -132,8 +145,7 @@ Go to your project page on FlutterFlow and follow the steps below to define the 4. On the right side, search and select the **Firestore** > **Delete Document** action. 5. In order to delete a specific document within a Firebase collection, you need to specify the reference to that document. The reference acts as a pointer to the exact document you want to delete. -
+
@@ -152,50 +164,49 @@ To manually query a collection, follow the steps below to define this action to 4. On the right side, search and select the **Firestore** > **Query Collection** action. 5. Choose the **Collection** you want to query. 6. Choose the **Query Type** among the following: - - **List of Documents:** Use this option when you need to query an entire list of documents from + - **List of Documents:** Use this option when you need to query an entire list of documents from a collection. This is useful for retrieving multiple documents that can be ordered or filtered by specific criteria, such as a keyword. - - **Single Document:** Select this when you want to fetch a specific single document from a + - **Single Document:** Select this when you want to fetch a specific single document from a collection, typically identified by its unique ID. - - **Count:** Choose this option to determine the number of documents that meet certain criteria + - **Count:** Choose this option to determine the number of documents that meet certain criteria without retrieving the documents themselves. This is useful for getting quick insights or summaries, like the total number of entries that match a filter. 7. You can also [Filter](#filtering-a-collection-query) and [Order](#ordering-a-collection-query) the query result. 8. Provide the **Action Output Variable Name**. This will be used to store the query result. -
+Keep result sets bounded with filters and limits. Firestore charges for reads and evaluates queries against security rules; rules are not post-query filters. Some compound queries require an index, and the Firebase error includes a link for creating a missing index. + +

-9. Now, you can use the *Action Output Variable Name* provided in the previous step to generate +9. Now, you can use the *Action Output Variable Name* provided in the previous step to generate children from a variable on **ListView**. -10. Finally, you can display data in a **Text** - widget. To do so, select the **Text widget > Properties Panel > Text > Set from Variable menu** +10. Finally, you can display data in a **Text** + widget. To do so, select the **Text widget > Properties Panel > Text > Set from Variable menu** **> [children_from_variable_name] item > select the field** you want to display.

-
+
#### Filtering a Collection Query Sometimes, you might need to filter a list based on a condition. For example, you might want to show only incomplete Todo items on the main listing. To add a filter when querying a collection: -- In the Action properties of **Query Collection Action**, scroll down and click on the **+ Filter** +- In the Action properties of **Query Collection Action**, scroll down and click on the **+ Filter** button at the bottom -- Find the **Field Name**, click on the Unset, and select a field on which you would like to apply +- Find the **Field Name**, click on the Unset, and select a field on which you would like to apply the filter. - Find the **Relation** dropdown, click on the **Unset**, and choose the relation among the list. - Find the **Value** property and set it to an appropriate value and click **Confirm**. :::info -- Select a filter relation that aligns with your specific needs. For instance, if you wish to display only incomplete todos, you can create a field named 'isDone,' set the relation to 'Equal To,' and define the value as 'False.' +- Select a filter relation that aligns with your specific needs. For instance, if you wish to display only incomplete todos, you can create a field named 'isDone,' set the relation to 'Equal To,' and define the value as 'False.' - Another example would be to showcase users older than 30; in this case, you'd create a 'Age' field, set the relation to 'Greater Than,' and specify the value as 30. - You can combine multiple filters using **AND** or **OR** operators to create more advanced filtering logic. This enables you to refine your data query to match specific conditions. ::: -
+
#### Ordering a Collection Query @@ -203,25 +214,24 @@ You might want to show your list based on a specific order. For example, you cou To specify the order when querying a collection: -- In the Action properties of **Query Collection Action**, scroll down and click on the **+ Order +- In the Action properties of **Query Collection Action**, scroll down and click on the **+ Order By** button at the bottom -- Find the **Field Name**, click on the **Unset**, and select the field which you would like to choose +- Find the **Field Name**, click on the **Unset**, and select the field which you would like to choose for ordering. -- Find **Order** dropdown, click on the Unset, and choose the order either Increasing or Decreasing and +- Find **Order** dropdown, click on the Unset, and choose the order either Increasing or Decreasing and click **Confirm**. :::info Choose the order based on your requirements. For instance, if you want to display Todo items sorted by their due dates, simply set the **Field Name** to date and the **Order** to Increasing. ::: -
+

:::warning -If you apply both filtering and ordering while querying a collection, an index is necessary -otherwise FlutterFlow will throw an error. +If you apply both filtering and ordering while querying a collection, an index is necessary +otherwise FlutterFlow will throw an error. [**Learn how to avoid the errors.**](../../firebase/connect-to-firebase-setup.md#adding-indexes) ::: @@ -232,15 +242,17 @@ When working with databases, you often need to create, update, or delete data. T By enabling Firestore batch write, you can group multiple operations and send them to the database as a single request. With this, either all the operations within the batch will succeed or none of them will be applied. This guarantees data consistency, so you don't end up with a partially updated state if something goes wrong during the process. +All operations in the batch must pass security rules, and the complete batch is subject to Firestore request, write, and payload limits. Split large workloads and use a trusted backend for privileged or high-volume processing. + :::tip -* You can learn more about +* You can learn more about [**Firestore Batch Write**](https://firebase.google.com/docs/firestore/manage-data/transactions#batched-writes). * If you are a newbie, we recommend watching [**this video**](https://youtu.be/dOVSr0OsAoU) first. ::: Suppose you have an e-commerce application, and after a successful order, you need to update the product inventory count and create a new document in the 'orders' collection. Using a batch write, you can combine these operations and execute them together to ensure data consistency. -To enable Firestore batch write, you must have multiple Firestore any combination of +To enable Firestore batch write, you must have multiple Firestore any combination of actions; inside the action editor, at the top right side, enable **Batch Firestore Writes**.
@@ -252,8 +264,7 @@ actions; inside the action editor, at the top right side, enable **Batch Firesto Sometimes, you might want to trigger an action whenever the data changes inside the collection. For instance, In a news app, you might want to notify users when new news is available, like this: -
+

@@ -264,6 +275,8 @@ To do so: 2. Now, on the widget with **Query Collection** or **Document from Reference**, open the **Action Flow Editor** and set **On Data Change** as the [Action Trigger](../../../resources/control-flow/functions/action-triggers.md). This ensures that any actions you add will be triggered whenever the data is updated, added, or deleted. 3. You can now [add any action](../../../resources/control-flow/functions/action-flow-editor.md#adding-an-action-example) you want to perform, such as showing a notification, refreshing the UI, or fetching related data. +Design this flow to be idempotent. A listener can emit more than once, reconnect, or receive a change caused by the action itself; writing back to the watched data without a guard can create an action loop. + :::info If you are using this trigger on a ListView, make sure to **disable** the **Infinite Scroll**. ::: @@ -273,9 +286,8 @@ If you are using this trigger on a ListView, make sure to **disable** the **Infi paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding height: 0, width: '100%'}}> - +
@@ -131,9 +143,8 @@ The rules set in the above examples are for simplification purposes. You should height: 0, width: '100%' }}> - +
::: @@ -103,7 +113,7 @@ Additionally, you can use multiple databases to simulate different environments To create a new database, go to the **Firebase Console > Firestore Database** section. Click the button next to the default database, i.e, **Add database**. Choose a region and configure your security rules. Once the new database is created, you can switch between databases using the dropdown. -Next, copy the new **Database ID** and navigate to **FlutterFlow > Settings and Integrations > Firebase > Advanced Settings**. Paste the ID into the **Firestore Database ID** input field. Finally, regenerate the config file. Your app will now use the newly created database. +Next, copy the new **Database ID** and navigate to **FlutterFlow > Settings and Integrations > Firebase > Advanced Settings**. Paste the ID into the **Firestore Database ID** input field. Finally, regenerate the config file. Your app will now use the selected database. Deploy and test security rules and indexes for that database separately.
Settings and paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding height: 0, width: '100%'}}> -
-

\ No newline at end of file +

diff --git a/docs/ff-integrations/database/local-sql/quickstart.md b/docs/ff-integrations/database/local-sql/quickstart.md index 54a3cb94a..249639f01 100644 --- a/docs/ff-integrations/database/local-sql/quickstart.md +++ b/docs/ff-integrations/database/local-sql/quickstart.md @@ -1,17 +1,31 @@ --- slug: /integrations/database/sqlite title: SQLite Quickstart -description: Learn how to quickly get started with SQLite in your FlutterFlow app for local data storage. -tags: [SQLite, Database, Quickstart, Local Storage] +description: >- + Learn how to quickly get started with SQLite in your FlutterFlow app for local + data storage. +tags: + - FlutterFlow + - Integrations + - Database sidebar_position: 1 -keywords: [FlutterFlow, SQLite, Database, Quickstart, Local Storage] +keywords: + - FlutterFlow + - SQLite + - Database + - Quickstart + - Local Storage +last_verified: 2026-09-02 --- - # SQLite SQLite is a compact, efficient database management system. Unlike conventional databases that require a server, SQLite is serverless and embeds directly into applications. -It's perfect for mobile apps where resources are limited, and a full-fledged database server is impractical. For example, it's ideal for a mobile app that needs to store data locally, such as a personal finance tracker or a health record app, especially when offline functionality is required. +It is useful for mobile apps that need structured local data and offline access without a database server. SQLite is local storage, not a synchronization service: it does not automatically share data between devices, back up user records, resolve conflicts, or restore data after the app's storage is cleared. + +:::warning[Sensitive local data] +The database file is not encrypted by default. Do not assume that SQLite alone protects financial, health, authentication, or other sensitive data. Apply platform-appropriate encryption, secure key management, access controls, retention, backup, and privacy design for your risk model. +::: :::caution Currently, we don't support SQLite on Web-based apps. @@ -19,8 +33,7 @@ Currently, we don't support SQLite on Web-based apps. Let's understand how you can utilize SQLite in your app with an example. An app where users can add, update, and delete Notes. Here's how it looks when completed: -
+

@@ -42,21 +55,22 @@ To enable SQLite in FlutterFlow, navigate to Settings and Integrations > Integra ## 2. Database configuration -In the database configuration step, you'll need to upload your SQLite database file and assign a name to it. This process is crucial for initializing the database when your app launches. +In the database configuration step, upload your SQLite database file and assign a name to it. The file provides the initial database installed with the app. -If you don't yet have an SQLite database, you can easily create one using tools like +Plan schema migrations before changing that file for an app users have already installed. Replacing the bundled database in a later build does not by itself guarantee that each device's existing writable database will be upgraded or that user-created data will be preserved. + +If you don't yet have an SQLite database, you can easily create one using tools like [sqlitebrowser](https://sqlitebrowser.org/). Simply download [sqlitebrowser](https://sqlitebrowser.org/dl/), create a new database, set up your tables, and optionally add some data. After preparing your database, upload the file to FlutterFlow to integrate it with your app. For this example, we'll create a "Notes" table with `ID`, `Title`, `Details`, `DueDate`, and `IsCompleted` as columns. :::warning -It is advisable to avoid using any SQL reserved keywords such as `type` and `data` as column names to prevent potential build errors or unexpected behavior. SQLite reserves certain words for its SQL syntax, and using these as identifiers without proper handling may cause issues. For a comprehensive list of reserved keywords, refer to the [**SQL reserved words**](https://en.wikipedia.org/wiki/List_of_SQL_reserved_words). +Avoid SQL keywords such as `type` and `data` as column names because they can cause build errors or unexpected behavior when they are not quoted correctly. See the authoritative [SQLite Keywords](https://www.sqlite.org/lang_keywords.html) list and quoting rules. ::: Here's how you can create and configure the database: -
+

@@ -94,6 +108,10 @@ In general, to add any query, you need to provide a name, the query statement, a ![img_1.png](imgs/img_1.png) ::: +:::danger[Query variables are not prepared parameters] +FlutterFlow's `${variableName}` syntax inserts values into the generated SQL string. Do not let untrusted input supply SQL fragments, identifiers, sort directions, or raw expressions. Validate numeric and identifier-like inputs against strict allowlists. For arbitrary user-entered text or other sensitive queries, use custom code that calls SQLite with bound `?` arguments rather than manual quoting; simply surrounding a value with single quotes does not prevent SQL injection. +::: + Below are the queries that we'll require for this example: #### 1. GetAllNotes @@ -104,8 +122,7 @@ This will retrieve all notes from the database. ``` Select * from Notes ``` -
+

@@ -118,8 +135,7 @@ This will add a new note to the database. INSERT INTO Notes (Title, Details, DueDate, IsCompleted) VALUES ('${title}', '${details}', ${dueDate}, 0); ``` -
+

@@ -130,7 +146,7 @@ This will update the existing note based on the note ID. ``` UPDATE Notes -SET +SET Title = '${title}', Details = '${details}', DueDate = ${dueDate}, @@ -138,8 +154,7 @@ SET WHERE ID = ${id}; ``` -
+

@@ -151,8 +166,7 @@ This will delete the note based on the note ID. DELETE FROM Notes WHERE ID = ${id}; ``` -
+
## 4. Display all notes @@ -172,8 +186,7 @@ Go to your project page and follow the steps below to define an SQLite query: - Click **Add Query** and set the Query Type to **SQLite Query**. - Select the **Query Name**. (Only Read Queries will be displayed here.) and click **Confirm**. -
+

@@ -181,11 +194,10 @@ Once you have the SQLite query defined, you can use the data retrieved from the - Select the widget (e.g., Text) on which you want to display the data. -- From the Properties Panel, open the Set from Variable menu > select [your query name] Row > +- From the Properties Panel, open the Set from Variable menu > select [your query name] Row > select the column data that you want display here and click **Confirm**. -
+

@@ -195,28 +207,26 @@ In our example, the due date is stored as a Unix timestamp, which isn't user-fri ## 5. Add note -You can add a new note in the database using the SQLite query Action with the type set to +You can add a new note in the database using the SQLite query Action with the type set to **Update Query** and Query Name to [AddNote](#2-addnote). Here's how you do it: -
+
## 6. Update note -For updating note values, like marking a note as completed or modifying other fields, utilize -the SQLite Query Action and set the type to **Update Query**. Here, set the Query Name to +For updating note values, like marking a note as completed or modifying other fields, utilize +the SQLite Query Action and set the type to **Update Query**. Here, set the Query Name to [Update Note](#3-updatenote). Here's how you do it: -
+
:::info @@ -231,14 +241,13 @@ com/embed/35564ad5e8be4f58aa72527bc6818183?sid=2740d823-df42-49c3-ae54-8e0e95a72 You can delete an existing note from the database using the [SQLite query action](../../../resources/control-flow/backend-logic/backend-query/sqlite-query.md) with the type set to *Update Query* and Query Name to **Delete Note**. -:::tip[Pro Tip] -To refresh the page, simply add an [**Update App State Action**](../../../resources/data-representation/app-state.md) Action with the Update Type set +:::tip[Pro Tip] +To refresh the page, simply add an [**Update App State Action**](../../../resources/data-representation/app-state.md) Action with the Update Type set to 'Rebuild Current Page'. ::: Here's how you do it: -
+

@@ -253,7 +262,7 @@ Check out the complete [**example project**](https://app.flutterflow.io/project/ Can SQLite handle complex data structures compared to App State Variables? -Yes, SQLite can handle complex data structures much more effectively. It allows for structured data storage, complex queries, sorting, and filtering, which are challenging to implement with app state variables. +SQLite is usually a better fit for relational, structured datasets that need queries, sorting, filtering, indexes, or transactions. App State is simpler for small UI or session values. Choose based on lifecycle, query needs, sensitivity, and data volume rather than assuming one is always better. @@ -261,7 +270,7 @@ Yes, SQLite can handle complex data structures much more effectively. It allows
Is SQLite a good choice for apps that require offline functionality? -Absolutely. SQLite stores data locally, making it an excellent choice for apps that need to operate offline. Users can access and manipulate data without needing an internet connection. +SQLite can read and write local data without an internet connection. If the app also needs cloud backup or cross-device state, you must design and test a separate synchronization layer, conflict policy, authentication model, and retry behavior.
@@ -269,7 +278,7 @@ Absolutely. SQLite stores data locally, making it an excellent choice for apps t Will using SQLite affect my app's performance compared to using App State Variables? -SQLite is designed to be lightweight and efficient, so it generally won't negatively impact your app's performance. In fact, for larger data sets, it's more efficient than storing data in app state variables. +SQLite is lightweight, but performance depends on schema design, indexes, query shape, result size, transactions, and device storage. Measure representative data on target devices and avoid loading unbounded result sets into the UI. @@ -277,7 +286,7 @@ SQLite is designed to be lightweight and efficient, so it generally won't negati How does SQLite ensure data security and integrity? -SQLite maintains data integrity and supports transactional operations. This means it ensures the database state remains consistent even in cases of unexpected interruptions, like app crashes or power failures. +SQLite supports constraints and transactions that can preserve database consistency when they are used correctly. It does not automatically validate business rules, encrypt the database, authenticate users, or prevent an authorized device user from accessing the file. Define constraints and transactions explicitly and test interruption and migration scenarios. diff --git a/docs/ff-integrations/database/refresh-db-request.md b/docs/ff-integrations/database/refresh-db-request.md index 672658103..fa0a1a721 100644 --- a/docs/ff-integrations/database/refresh-db-request.md +++ b/docs/ff-integrations/database/refresh-db-request.md @@ -1,16 +1,26 @@ --- slug: /integrations/database/refresh-db-request title: Refresh DB Request Action -description: Learn how to use the Refresh DB Request action in your FlutterFlow app to refresh your database content. -tags: [Database, Refresh, Action] +description: >- + Learn how to use the Refresh DB Request action in your FlutterFlow app to + refresh your database content. +tags: + - FlutterFlow + - Integrations + - Database sidebar_position: 4 -keywords: [FlutterFlow, Database, Refresh, Action] +keywords: + - FlutterFlow + - Database + - Refresh + - Action +last_verified: 2026-09-02 --- - - # Refresh Database Request [Action] -Using this action, you can see the updated values of an item inside the scrollable widgets such as ListView, GridView, StaggeredView, Row, and Column. +Use this action to rerun a supported one-time backend query and rebuild its target widget with the result. Typical targets include ListView, GridView, StaggeredView, Row, and Column. + +Refreshing does not bypass database security rules, API authorization, query filters, or backend errors. It also does not guarantee that another system has finished an earlier asynchronous write. Chain the refresh after the write completes when the refreshed data depends on that write.
-
-

\ No newline at end of file +

+ +## Related documentation + +See [Backend Query](/resources/backend-query) to configure the query this action refreshes. diff --git a/docs/ff-integrations/database/supabase/database-actions.md b/docs/ff-integrations/database/supabase/database-actions.md index 003341513..ed1826017 100644 --- a/docs/ff-integrations/database/supabase/database-actions.md +++ b/docs/ff-integrations/database/supabase/database-actions.md @@ -1,16 +1,29 @@ --- slug: /integrations/database/supabase/database-actions title: Database Actions -description: Learn about Supabase Database actions in your FlutterFlow app, including how to perform various database operations. -tags: [Supabase, Database, Actions] +description: >- + Learn about Supabase Database actions in your FlutterFlow app, including how + to perform various database operations. +tags: + - FlutterFlow + - Integrations + - Database sidebar_position: 1 -keywords: [FlutterFlow, Supabase, Database, Actions] +keywords: + - FlutterFlow + - Supabase + - Database + - Actions toc_max_heading_level: 5 +last_verified: 2026-09-02 --- - # Supabase Database Actions -The Supabase Database Actions allow you to **Insert, Update**, or **Delete a Row** from a Supabase table. +The Supabase Database Actions allow you to **Insert, Update**, or **Delete a Row** from a Supabase table. + +:::warning[Secure every table with Row Level Security] +FlutterFlow client apps use a public Supabase key, so database authorization must be enforced with [Row Level Security (RLS)](https://supabase.com/docs/guides/database/postgres/row-level-security) policies. UI visibility and query filters are not security controls. Enable RLS, write least-privilege policies for `select`, `insert`, `update`, and `delete`, and test as anonymous, authenticated, owner, and non-owner users. Never put a Supabase `service_role` key in a client app. +::: Note that beyond actions, you can also setup [**Backend Queries**](../../../resources/control-flow/backend-logic/backend-query/backend-query.md) for Supabase. This includes realtime streaming queries. @@ -30,13 +43,13 @@ Following are the types of actions you can perform on a Supabase table. - [**Insert Row**](#insert-row-action): Adds a new row in a table. - [**Update Row**](#update-row-action)**:** Updates a row with the specified values. - [**Delete Row**](#delete-row-action)**:** Deletes a row from a table. -- [**Query Rows**](#query-rows-action): Retrieves +- [**Query Rows**](#query-rows-action): Retrieves rows from a table based on specific criteria or conditions. ### Insert Row [Action] 1. Select the **Widget** (e.g., Button) on which you want to define the action. -2. Select **Actions** from the Properties Panel (the right menu), and click **Open**. This will +2. Select **Actions** from the Properties Panel (the right menu), and click **Open**. This will open an **Action Flow Editor** in a new popup window. 1. Click on **+ Add Action**. @@ -50,19 +63,18 @@ Following are the types of actions you can perform on a Supabase table. 6. Similarly, add the field for the other UI elements. :::tip[Pro Tip] -While adding this action, you can leave the **id** (if marked as *Primary*) and +While adding this action, you can leave the **id** (if marked as *Primary*) and **created_at** (if default value is `now()`) fields. Supabase will automatically add values for these fields. ::: -
+
### Update Row [Action] 1. Select the **Widget** (e.g., Button) on which you want to define the action. -2. Select **Actions** from the Properties Panel (the right menu), and click **Open**. This will +2. Select **Actions** from the Properties Panel (the right menu), and click **Open**. This will open an **Action Flow Editor** in a new popup window. 1. Click on **+ Add Action**. @@ -71,22 +83,23 @@ com/embed/f2a75f9b0e144f6aab06cc1f0965541b?sid=6f57ff8a-ca2a-4c47-833d-03fa928b8 4. Optional: If you want to get the rows after the update is finished, enable the **Return Matching Rows** option. 5. Now, you must set the row you want to update. Usually, this is done by finding a row in a table that matches the current row ID. To do so, click **+ Add Filter** button inside the **Matching Rows** section. - 1. Set the **Field Name** to the field that contains the IDs. Typically, this is the + 1. Set the **Field Name** to the field that contains the IDs. Typically, this is the **id** column. 2. Set the **Relation** to **Equal To** because you want to find a row with the exact id. 3. Into the **Value Source**, you can select the **From Variable** and provide the id of the row for which you just updated values in the UI. 6. Under the **Set Fields** section, click on the **+ Add Field** button. 7. Click on the Field Name. - + 1. Scroll down to find the **Value Source** dropdown and change it to **From Variable**. 2. Click on **UNSET** and select **Widget State > Name** of the TextField. 8. Similarly, add the field for the other UI elements. +Use a unique key in **Matching Rows** whenever you intend to change one row. A broad or missing filter can update every row the current RLS policy permits. + :::tip[How to & Tips] -
+

@@ -106,22 +119,23 @@ Go to your project page on FlutterFlow and follow the steps below to define the 1. Click on **+ Add Action**. 2. On the right side, search and select the **Supabase** -> **Delete Row** action. 3. Set the **Table** to your table name (e.g., assignments). - 4. Optional: If you want to know which rows were deleted from a table, enable the **Return + 4. Optional: If you want to know which rows were deleted from a table, enable the **Return Matching Rows** option. 5. Now, you must set the row you want to delete. Usually, this is done by finding a row in a table that matches the current row ID. To do so, click **+ Add Filter** button inside the **Matching Rows** section. - 1. Set the **Field Name** to the field that contains the IDs. Typically, this is the + 1. Set the **Field Name** to the field that contains the IDs. Typically, this is the **id** column. 2. Set the **Relation** to **Equal To** because you want to find a row with the exact id. 3. Into the **Value Source**, you can select the **From Variable** and provide the id of the row you want to delete. -
+Confirm destructive actions where appropriate and use a unique key in **Matching Rows**. A broad or missing filter can delete every row the current RLS policy permits. + +

:::tip -You can chain the [**Refresh Database Request**](../refresh-db-request.md) action after this action to remove the +You can chain the [**Refresh Database Request**](../refresh-db-request.md) action after this action to remove the deleted items from the list. ::: @@ -145,30 +159,28 @@ To manually query a Supabase table, follow the steps below to define this action

-
+

-8. Now, you can use the **Action Output Variable Name** provided in the previous step to generate +8. Now, you can use the **Action Output Variable Name** provided in the previous step to generate children from a variable on **ListView**. 9. Finally, you can display data in a **Text** widget. To do so, select the **Text widget > Properties Panel > Text > Set from Variable menu > ***[children_from_variable_name]*** item > Get Row Field > select the row field** you want to display. -
+
#### Filtering table data -Sometimes you might want to filter a list based on a condition. For example, showing only +Sometimes you might want to filter a list based on a condition. For example, showing only completed assignments. You can do so by adding the Filter while you query a Supabase table. Let's see how to filter the Supabase table to display only desired items: -- In your **Action properties** of Query Rows action, scroll down and click on the **+ Add Filter** +- In your **Action properties** of Query Rows action, scroll down and click on the **+ Add Filter** button at the bottom. -- Find the **Field Name**, click on the Unset, and select a column on which you would like to apply +- Find the **Field Name**, click on the Unset, and select a column on which you would like to apply the filter. - Find the **Relation** dropdown, click on the Unset, and choose the relation amongst the list. - Find the **Value** property and set it to an appropriate value and click Confirm. @@ -191,8 +203,7 @@ You could choose a filter relation based on your requirements. For example: You can combine multiple filters using **AND** or **OR** operators to create more advanced filtering logic. This enables you to refine your data query to match specific conditions. ::: -
+
#### Ordering table data @@ -200,24 +211,19 @@ You might want to show a list from the Supabase table in a specific order. For e To specify the order: -- In your **Action properties** of Query Rows action, scroll down and click on the **+ Add Order** +- In your **Action properties** of Query Rows action, scroll down and click on the **+ Add Order** button at the bottom. - Set the **Table Field Name** to the column you would like to choose for ordering. -- Find **Order** dropdown, click on the Unset and choose the order either **Increasing** or **Decreasing** and +- Find **Order** dropdown, click on the Unset and choose the order either **Increasing** or **Decreasing** and click **Confirm**. :::tip You could choose the order based on your requirements. For example, to show assignments in order of due date, set Table Field Name to due_date and Order to Increasing. ::: -
+

-:::info -Additional Note: Currently, you can only add "and" conditions to Supabase query filters. If you want to add an "or" filter like "status == 5 or status == 8", you can consider logic to apply "status in (5,8)" or any other logic. Fully customizable using API calls or custom actions. -::: - ## Trigger Action On Data Change Sometimes, you may want to trigger an action whenever data changes in a Supabase table. For instance, in an ecommerce app, you might want to notify users on the orders page when the status of their order is updated. @@ -228,6 +234,8 @@ To respond to data changes in a Supabase table: 2. On the widget with the **Supabase Query**, open the **Action Flow Editor** and set **On Data Change** as the [Action Trigger](../../../resources/control-flow/functions/action-triggers.md). This ensures that any actions you add will be triggered whenever the data is updated, added, or deleted. 3. You can now [add any action](../../../resources/control-flow/functions/action-flow-editor.md#adding-an-action-example) you want to perform, such as showing a notification, refreshing the UI, or fetching related data. +Supabase Realtime must be enabled for the table, and the signed-in user must pass the applicable RLS policies. Streaming queries have stricter filter support than one-time queries. Design the action to be idempotent because reconnects or writes made by the action itself can produce repeated events or loops. Review Supabase's [Postgres Changes](https://supabase.com/docs/guides/realtime/postgres-changes) behavior and limits before using the trigger at scale. + :::info If you are using this trigger on a ListView, make sure to **disable** the **Infinite Scroll**. ::: @@ -237,9 +245,8 @@ If you are using this trigger on a ListView, make sure to **disable** the **Infi paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding height: 0, width: '100%'}}> - -As soon as the process is completed, you will see the following view in your Firebase Settings dashboard. +As soon as the process is completed, you will see the following view in your Firebase Settings dashboard. Firebase Project Created #### Enable Firebase Authentication -If you want to use the Firebase Authentication in your app or the Firebase Content Manager, you must enable the authentication in the Firebase console and enable the 'Email/Password' sign-in. +If your app uses Firebase Authentication, enable Authentication in the Firebase console and configure only the sign-in providers your app needs. The Firestore Content Manager connection also requires Email/Password sign-in to be enabled for its managed access flow. #### Enable Firebase Storage If you plan to use Firebase storage in your app, click on the Enable Storage on Firebase and enable it on Firebase console. @@ -77,8 +91,11 @@ In the dialog, scroll down to **Setup Firebase**, check that option, and click * 8. Select **+ Add Another Role** again. Under **Select A Role**, search for **Cloud Functions Admin**. Select **Cloud Functions Admin**. :::info -Note: The option to add Cloud Functions Admin may only show up if you are on a Firebase Blaze plan. In addition, you may need to [enable cloud functions](https://console.cloud.google.com/marketplace/product/google/cloudfunctions.googleapis.com) first. -Cloud Functions Admin permissions are required for several FlutterFlow features (e.g., Push Notifications). Adding this Cloud Functions Admin is optional, but not doing so will prevent you from using any functions that require Cloud Functions. +Cloud Functions Admin permissions are required for FlutterFlow features that deploy Cloud Functions, such as Push Notifications. This role is optional if you do not use those features. Enabling the Cloud Functions API and upgrading the Firebase project to the Blaze plan are separate prerequisites for deploying functions; the billing plan does not control whether the IAM role appears. +::: + +:::caution[Grant only required project access] +These roles let FlutterFlow configure resources in this Firebase project. Grant them only to the documented FlutterFlow principal and only on the intended project. Periodically review project members and remove access when FlutterFlow no longer needs to manage the project. ::: #### Connect and autogenerate files @@ -98,7 +115,7 @@ Do not close or refresh the page while the files are being generated. ## Connect to Firebase on Creating a New FlutterFlow Project -If you know you'll be integrating Firebase as you create your project, you can do the following: +If you know you'll be integrating Firebase as you create your project, you can do the following: #### Step 1: Create a new project and enable Firebase @@ -106,21 +123,21 @@ First, create a new project, and while doing so, keep the Setup Firebase option Alt text -#### Step 2: Connect to Firebase +#### Step 2: Connect to Firebase -If you'd like FlutterFlow to create a Firebase project for you, click **"+ Create Project"** and follow the [related steps](#create-a-new-firebase-project-from-flutterflow). Alternatively, if you wish to connect an existing Firebase project manually, please follow the [manual steps here](#connect-an-existing-firebase-project-manually). +If you'd like FlutterFlow to create a Firebase project for you, click **"+ Create Project"** and follow the [related steps](#create-a-new-firebase-project-from-flutterflow). Alternatively, if you wish to connect an existing Firebase project manually, please follow the [manual steps here](#connect-an-existing-firebase-project-manually). #### Step 3: Enable Authentication -Turn on the Enable Authentication to allow users to log into your app using various sign-in methods, including email and password, social media providers, and even phone number. +Turn on the Enable Authentication to allow users to log into your app using various sign-in methods, including email and password, social media providers, and even phone number. -**Note:** this step only enables authentication. You will need to complete an additional setup to implement authentication logic later. +**Note:** this step only enables authentication. You will need to complete an additional setup to implement authentication logic later. Enable Authentication During Project Creation -## Enable Firestore for Database Access +## Enable Firestore for Database Access If you plan to use Firestore Database as your backend, follow these additional steps to enable Firestore. This will allow you to create collections and add documents directly from FlutterFlow. @@ -130,14 +147,12 @@ To configure Firestore Database: Alt text -2. Next, you will need to set your **Firebase security rules**. To get started quickly, you can select Start in test mode and select Next. +2. Next, set your **Firebase security rules**. Prefer production mode and deploy rules that match your app's access model. If you temporarily select **Start in test mode** for a disposable prototype, treat the database as publicly accessible during the test window and replace those rules before adding real user data or sharing the app. Alt text -:::info -We recommend updating your Firebase security rules before deploying your app. Please see [this -link](../database/cloud-firestore/firestore-rules.md) for additional information on -Firestore security rules. +:::warning +Test-mode rules are not production security. Configure, test, and deploy [Firestore Security Rules](../database/cloud-firestore/firestore-rules.md) before storing sensitive data. Authentication alone does not restrict a collection unless the rules enforce the intended authorization. ::: 3. Next, you will need to choose the location where your Firestore data will be stored. From the dropdown, select a location and then select Enable. Please see this link for additional information on Firebase locations. @@ -162,18 +177,21 @@ Here are the steps to deploy indexes. If you add a filtering/ordering on the query or change the existing filtering/ordering settings, you should deploy the Firestore Indexes again. ::: -
+
## Enable Billing -If you want to deploy [Cloud Functions](https://firebase.google.com/products/functions) (e.g., Braintree payments, Push Notifications) or use [Firebase Cloud Storage](https://firebase.google.com/products/storage), you will need to enable billing for your Firebase project. Please follow these steps to enable billing: +To deploy [Cloud Functions](https://firebase.google.com/products/functions) used by features such as Braintree payments or Push Notifications, or to use [Cloud Storage for Firebase](https://firebase.google.com/products/storage), place the project on the pay-as-you-go Blaze plan. Since February 3, 2026, Cloud Storage for Firebase requires Blaze to provision or retain access to buckets; eligible no-cost usage can still apply on Blaze. 1. From the Firebase dashboard of your project, navigate to the far left menu. Under Build, select **Functions** and then select **Upgrade project**. -2. Select **Purchase**. If this is your first time enabling billing, you will be taken to a new page to provide your payment information. Otherwise, you can set a project budget. Please see [this link](https://firebase.google.com/pricing) for additional information on Firebase pricing. +2. Select **Purchase**. If this is your first time enabling billing, you will be taken to a page to provide payment information. Otherwise, you can select an existing billing account. Configure budgets and alerts, but remember that budget alerts notify you and do not automatically cap usage or charges. Review [Firebase pricing](https://firebase.google.com/pricing) and the [current Cloud Storage billing requirements](https://firebase.google.com/docs/storage/faqs-storage-changes-announced-sept-2024). Alt text + +## Related documentation + +See [App Check](/integrations/firebase/app-check) for a related FlutterFlow workflow. diff --git a/docs/ff-integrations/firebase/crashlytics.md b/docs/ff-integrations/firebase/crashlytics.md index 9da8caf0e..fdaae8427 100644 --- a/docs/ff-integrations/firebase/crashlytics.md +++ b/docs/ff-integrations/firebase/crashlytics.md @@ -2,11 +2,16 @@ slug: /integrations/firebase/crashlytics title: Crashlytics description: Learn how to integrate Firebase Crashlytics in your FlutterFlow app. -tags: [Firebase, Crashlytics] +tags: + - FlutterFlow + - Integrations + - Firebase sidebar_position: 2 -keywords: [FlutterFlow, Firebase, Crashlytics] +keywords: + - FlutterFlow + - Firebase + - Crashlytics --- - # Firebase Crashlytics [Firebase Crashlytics](https://firebase.google.com/products/crashlytics) is a crash-reporting tool that helps you catch errors. It enables you to troubleshoot the issue by logging the details, such as the exact line number that caused the error, device name, OS version, and time when the crash happened. @@ -21,4 +26,4 @@ You can see all the logged errors/crashes inside the Crashlytics dashboard of yo 1. Click on the issue name to see its details. 2. To test the crash on your app, [download the app](../../ff-concepts/advanced/flutterflow-cli/exporting-projects.md), add a code that throws an error, and run it on a mobile device or emulator with an active internet connection. -![Test crash](imgs/test-crash.avif) \ No newline at end of file +![Test crash](imgs/test-crash.avif) diff --git a/docs/ff-integrations/firebase/performance-monitoring.md b/docs/ff-integrations/firebase/performance-monitoring.md index 1116928f6..9de624f50 100644 --- a/docs/ff-integrations/firebase/performance-monitoring.md +++ b/docs/ff-integrations/firebase/performance-monitoring.md @@ -1,12 +1,20 @@ --- slug: /integrations/firebase/performance-monitoring title: Performance Monitoring -description: Learn how to integrate Firebase Performance Monitoring in your FlutterFlow app. -tags: [Firebase, Performance Monitoring] +description: >- + Learn how to integrate Firebase Performance Monitoring in your FlutterFlow + app. +tags: + - FlutterFlow + - Integrations + - Firebase sidebar_position: 4 -keywords: [FlutterFlow, Firebase, Performance Monitoring] +keywords: + - FlutterFlow + - Firebase + - Performance Monitoring +last_verified: 2026-09-02 --- - # Performance Monitoring [Firebase Performance Monitoring](https://firebase.google.com/docs/perf-mon) is a tool that *automatically* collects performance data from your app and provides insights through the Firebase console. It can monitor both network requests and specific parts of your code. @@ -18,4 +26,20 @@ Enabling performance monitoring is beneficial for: - **Data-Driven Decisions**: Make optimization decisions based on real performance data. - **Monitor Network Calls**: See how long network requests take, helping identify slow APIs or network issues. -To enable performance monitoring, navigate to Settings and Integrations > Project Setup > Firebase > Open the Performance Monitoring section and Enable Performance Monitoring toggle. \ No newline at end of file +After you [connect the FlutterFlow project to Firebase](connect-to-firebase-setup.md), navigate to **Settings and Integrations > Project Setup > Firebase**, open **Performance Monitoring**, and turn on **Enable Performance Monitoring**. Regenerate Firebase configuration files if FlutterFlow prompts you, then rebuild the app. + +## Verify data collection + +Run a non-production build on each supported platform, exercise startup and several HTTP requests, and check the **Performance** dashboard in the Firebase console. Data may take a few minutes to appear. Firebase automatically records lifecycle and HTTP/S network traces; individual Flutter screen-rendering traces are not automatically available because Flutter renders through one native view controller. + +Use custom code traces when you need to measure a specific workflow such as loading images or querying a database. Start and stop every trace reliably, and use bounded, low-cardinality metric or attribute values. + +:::warning[Privacy and consent] +Performance Monitoring transmits performance and app/device attributes to Firebase. Review the [data Firebase collects](https://firebase.google.com/docs/perf-mon/data-collection), update your privacy disclosures and consent flow where required, and follow applicable laws and store policies. Do not put names, email addresses, user IDs, tokens, full query strings, or other personal or secret data in trace names, metric names, attributes, or URLs. +::: + +For custom initialization or consent-controlled collection in exported code, follow Firebase's [collection-control guidance](https://firebase.google.com/docs/perf-mon/disable-sdk) and test that both automatic and custom collection behave as intended. + +## Related documentation + +See [Firebase's Flutter setup and validation guide](https://firebase.google.com/docs/perf-mon/flutter/get-started) for platform behavior and troubleshooting details. diff --git a/docs/ff-integrations/firebase/remote-config.md b/docs/ff-integrations/firebase/remote-config.md index 752d24037..ae7f76fd0 100644 --- a/docs/ff-integrations/firebase/remote-config.md +++ b/docs/ff-integrations/firebase/remote-config.md @@ -2,21 +2,31 @@ slug: /integrations/firebase/remote-config title: Remote Config description: Learn how to integrate Firebase Remote Config in your FlutterFlow app. -tags: [Firebase, Remote Config] +tags: + - FlutterFlow + - Integrations + - Firebase sidebar_position: 1 -keywords: [FlutterFlow, Firebase, Remote Config] +keywords: + - FlutterFlow + - Firebase + - Remote Config +last_verified: 2026-09-02 --- - # Remote Config -[Firebase remote config](https://firebase.google.com/docs/remote-config) allows you to control your app's behavior and appearance without pushing an app update. For example, you could use it to change or show/hide certain elements of your app, such as a promo banner and Santa hat, or use it as a feature flag (payments, food delivery) with no need to publish an app update. +[Firebase Remote Config](https://firebase.google.com/docs/remote-config) lets you change supported app behavior and appearance without publishing a new app build. For example, you can show a promotional banner or gradually expose a non-security-sensitive feature. + +:::danger[Remote Config is not secret or authorization storage] +Users can inspect values delivered to a client app. Never store API secrets, credentials, private endpoints, entitlement decisions, prices that must be enforced, or authorization rules in Remote Config. Enforce security-sensitive decisions on a trusted backend and use Remote Config only to adjust the client experience. +::: ![Using Firebase Remote Config to show/hide a feature](imgs/show-hide-fi.avif) -When you enable the Remote Config, you must specify the parameter in our builder (called 'in-app defaults') and inside the Remote Config dashboard of your [Firebase console](https://console.firebase.google.com/). When the app starts, it fetches config values from the Firebase console, and for any reason, if it fails, your app will use the in-app defaults. +When you enable Remote Config, define each parameter in FlutterFlow as an **in-app default** and define the corresponding key in your [Firebase console](https://console.firebase.google.com/). On startup, the generated app fetches and activates eligible remote values. If no fetched value is available or activation fails, the app uses the in-app default, so every default must be safe and usable on its own. :::warning -The app will try to fetch values every time it starts. However, due to the minimum fetch interval of 1 hour (set by default), the values won't be fetched more than once in 1 hour. +The app attempts a fetch at startup, but FlutterFlow configures a one-hour minimum fetch interval. Starting the app repeatedly within that interval generally reuses the last activated value. Published changes are therefore not an instant-delivery or emergency kill-switch mechanism. ::: ## Using Firebase Remote Config @@ -35,25 +45,26 @@ You will be able to dynamically control your app using the parameters created in To create the parameter: -1. Navigate to the [Firebase Console](https://console.firebase.google.com/u/0/) > Enagage > Remote Config** page. +1. Open your project in the [Firebase console](https://console.firebase.google.com/u/0/) and navigate to **Remote Config** (currently under **DevOps & Engagement**). 2. If this is the first time, click **Create configuration** button. 3. Click **Add parameter**. This will open the **Create parameter** section on the right side. 4. Enter the **Parameter name** (e.g., *show_promo_banner*, *primary_color*, etc.). 5. Set the **Data type** among the *String*, *Number*, *Boolean*, and *JSON*. 6. Set the **Default value**. -7. If you enable the **Use in-app default** toggle, any change made to this parameter from here won't be reflected in your app. Instead, your app will use values from the parameters defined in our builder (see how to create it in the [next step](#3-add-parameter-in-flutterflow)). +7. If you select **Use in-app default**, Firebase sends no backend value for that parameter and the app uses the default defined in FlutterFlow. Otherwise, set a backend default and any conditional values you need. 8. Click **Save**. 9. Click **Publish Changes** to make this parameter immediately available to your app. +If several conditions match, the first condition in Firebase's ordered list takes precedence. Test default, conditional, offline, and failed-fetch behavior before relying on a parameter in production. +
-

- diff --git a/docs/ff-integrations/google-cloud/secure-keys.md b/docs/ff-integrations/google-cloud/secure-keys.md index 23875d0df..ff746fb04 100644 --- a/docs/ff-integrations/google-cloud/secure-keys.md +++ b/docs/ff-integrations/google-cloud/secure-keys.md @@ -1,20 +1,28 @@ --- slug: /best-practices/secure-api-keys title: Secure API Keys -description: Learn best practices for securing API keys in your FlutterFlow app, including key restrictions, geographical restrictions, IP address binding, and service-specific limitations. -tags: [API Keys, Security, Best Practices, Google Cloud] +description: >- + Learn best practices for securing API keys in your FlutterFlow app, including + key restrictions, geographical restrictions, IP address binding, and + service-specific limitations. +tags: + - FlutterFlow + - Best Practices sidebar_position: 1 -keywords: [FlutterFlow, API Keys, Security, Best Practices, Google Cloud] +keywords: + - FlutterFlow + - API Keys + - Security + - Best Practices + - Google Cloud + - restrict a Google Cloud API key used by FlutterFlow +ai_queries: + - restrict a Google Cloud API key used by FlutterFlow +last_verified: 2026-09-02 --- - # Best Practices: Secure API Keys -Google Cloud API key restriction is essential for managing access and enhancing security when -working with Google Cloud services. This overview explains how to effectively restrict API keys, -allowing developers to control how and where their keys can be used. Developers can set geographical -restrictions, bind keys to specific IP addresses, or limit usage to particular services. These -measures ensure that API keys are secured, helping to protect projects and maintain optimal -functionality. +Google Cloud API key restrictions reduce how an exposed key can be abused. Client API keys embedded in Android, iOS, or web builds can be inspected, so do not treat them as secrets. Create separate keys for each platform and environment, apply both an application restriction and API restrictions, and monitor usage and billing. To minimize potential damage from compromised API keys: @@ -24,15 +32,13 @@ To minimize potential damage from compromised API keys: - **Delete unnecessary API keys:** Remove any API keys that are no longer required to reduce exposure to attacks. -- **Rotate your API keys periodically:** Regularly create new API keys, delete the old ones, and - update your applications to use the new keys. This practice helps maintain security and limit the - lifespan of any single key. +- **Rotate safely when needed:** Create and restrict the replacement, update and release every consumer, verify traffic on the new key, and only then revoke the old key. Rotate immediately after suspected compromise. + +- **Keep server credentials off clients:** A key or credential that grants privileged or billable server access must stay behind a trusted backend. Do not put service-account keys, unrestricted server keys, or secrets in FlutterFlow client state, custom code, assets, or Remote Config. ## Add restrictions to your API key -API keys are unrestricted by default. Unrestricted keys are insecure because they can be used by anyone, from anywhere. You can add either [application restrictions](https://cloud.google.com/docs/authentication/api-keys?#adding-application-restrictions) or [API restrictions](https://cloud.google.com/docs/authentication/api-keys?#api_key_restrictions) to -enhance -security. +API keys are unrestricted by default. Apply both [application restrictions](https://cloud.google.com/docs/authentication/api-keys#adding-application-restrictions) and [API restrictions](https://cloud.google.com/docs/authentication/api-keys#api_key_restrictions) whenever the target service supports them. Use HTTP referrers for a web key, Android app restrictions with the package name and signing-certificate fingerprint for Android, iOS app restrictions with the bundle identifier for iOS, and IP restrictions only for calls from servers with stable egress addresses. In the following example, we will use the **Map API keys** and restrict them to specific platforms using @@ -54,7 +60,7 @@ Follow the steps below to enable the iOS key exclusively for iOS apps with a uni height: 0, width: '100%' }}> - +Enable only the APIs the app actually uses. Google Maps Platform requires a billing account, even when usage remains within an applicable no-cost threshold. Configure quotas, budgets, and billing alerts; budget alerts do not automatically stop charges. + +

:::warning -To secure your API keys, refer to the -[**Best Practices guide: Secure API Keys**](../../google-cloud/secure-keys.md) +Create a separate key for web, Android, and iOS. Apply the correct application restriction and restrict each key to only the Maps Platform APIs that platform uses. Client map keys are visible in the distributed app, so restrictions—not secrecy—are the primary control. See [Secure API Keys](../../google-cloud/secure-keys.md). ::: - Click on the Credentials menu from the left panel. @@ -63,14 +72,11 @@ Firebase) in the Google developer console, here are the steps to create one: - Click on the **API Key** to create a new key for the Android app. Similarly, create one for iOS and Web. -
+
## Add Places APIs -You can [enable the **Places API**](https://console.cloud.google.com/apis/library/places-backend.googleapis.com) from your Google Cloud Console — make sure you are in the correct Google Cloud project. **Please note** that the current [PlacePicker widget](../../maps/google-maps/place-picker-widget.md) uses the legacy Places API. We plan to update the PlacePicker widget soon to support the new API. In the meantime, ensure that the legacy Places API is enabled for full functionality. +You can [enable the **Places API**](https://console.cloud.google.com/apis/library/places-backend.googleapis.com) from Google Cloud Console—make sure you selected the same project as the API key. The current [PlacePicker widget](../../maps/google-maps/place-picker-widget.md) uses the legacy Places API endpoints, so the legacy **Places API** must be available for the project. **Places API (New)** alone is not a drop-in replacement for this widget. Google restricts new access to legacy services, so confirm availability in your project before committing to the PlacePicker for a new production app. ![places-api.png](imgs/places-api.png) - - diff --git a/docs/ff-integrations/maps/google-maps/google-maps-widget.md b/docs/ff-integrations/maps/google-maps/google-maps-widget.md index fa39318a8..18e5ba46e 100644 --- a/docs/ff-integrations/maps/google-maps/google-maps-widget.md +++ b/docs/ff-integrations/maps/google-maps/google-maps-widget.md @@ -2,10 +2,18 @@ slug: /integrations/google-maps/google-maps-widget title: Google Maps Widget description: Learn how to add and configure the Google Maps widget in your FlutterFlow app. -tags: [Google Maps, Widget, Integration] +tags: + - FlutterFlow + - Integrations + - Google Maps sidebar_position: 2 -keywords: [FlutterFlow, Google Maps, Widget, Integration] +keywords: + - FlutterFlow + - Google Maps + - Widget + - Integration toc_max_heading_level: 4 +last_verified: 2026-09-02 --- import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; @@ -29,6 +37,10 @@ ensure they meet your app development needs before integration. Ensure you have added the [**Google Map API keys**](generate-maps-keys.md#get-api-keys) before adding the Google Maps widget to your project ::: +:::warning[Location privacy] +Request device location only when the user invokes a feature that needs it, explain the purpose, and handle denied, restricted, unavailable, and approximate-location states. Minimize retention of precise coordinates and update privacy disclosures and store declarations where required. +::: + ## Add Google Map widget 1. Open the Widget Palette and locate the **Google Map** widget under the **Base Elements** tab. You @@ -51,12 +63,11 @@ Ensure you have added the [**Google Map API keys**](generate-maps-keys.md#get-ap 5. To customize the visual appearance of your map, navigate to the **Properties Panel > Map Style**. -6. To set the **initial zoom level** of the map, go to the **Properties Panel > Initial Zoom** +6. To set the **initial zoom level** of the map, go to the **Properties Panel > Initial Zoom** of Map and enter the desired value. Note that a higher value will zoom in on the map while a lower value will zoom out. -
+
@@ -68,6 +79,8 @@ If you don't see your current location while testing, make sure you have enabled ![location-browser.png](../imgs/location-browser.png) ::: +Do not assume **Current Device Location** is immediately available. Provide a fallback location or loading/error state before using it as the initial map center. + ## Markers A marker is an icon that appears over the map, indicating a location. To add markers: @@ -85,16 +98,16 @@ A marker is an icon that appears over the map, indicating a location. To add mar - In Marker Document, set the source of markers as shown in the following video. -
+
### Set Markers from List of LatLng If you choose **LatLng**, you must provide a source that contains a list of locations as Data Type (LatLng) (e.g., App State > [variable_name] (List of **LatLng**)). -
+Keep marker lists bounded. Large dynamic marker sets increase query cost, memory use, and rendering work; filter to the visible or relevant data and test on representative devices. + +
### Changing Marker Color @@ -115,16 +128,14 @@ engaging, while also aligning with your app's branding. To set an image as a mar Path field. - To provide an image from your system, set the Image Type to **Asset** and upload the image. -
+
### Centering map on marker tap To center a map on a marker tap, move to the **Properties Panel > Google Map > enable the Centering Map on Marker Tap toggle**. -
+
## On Marker Tap [Action Trigger] @@ -155,8 +166,7 @@ if you wish to restrict the zoom functionality. To access these settings, navigate to the **Properties Panel > Google Map > Allows Interacting with the Map**. -
+
#### Map Takes Gesture Preference When this is turned on, any gestures, such as zooming or dragging, will only affect the map, not the rest of the page. This is helpful if your map is inside a scrollable page, so users can interact with the map without accidentally scrolling the whole page. @@ -172,9 +182,8 @@ This setting is only available if **Allow Interacting** and **Allow Zooming** ar paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding height: 0, width: '100%'}}> - +
### Showing Compass @@ -246,8 +253,7 @@ Enabling compass will allow users to bring the map to its original direction. To enable the compass, navigate to the **Properties Panel > Google Map > enable the Show Compass toggle**. -
+
### Enabling map toolbar @@ -257,8 +263,7 @@ It offers quick access to either a map view or directions in the Google Maps mob To enable the toolbar, navigate to the **Properties Panel > Google Map > enable the Show Map Toolbar toggle**. -
+
### Showing Traffic on Map @@ -268,8 +273,7 @@ decide on a better route. To show live traffic on a map, navigate to the Properties Panel > Google Map > enable the Show Traffic on Map toggle. -
+
## FAQ
@@ -277,4 +281,4 @@ com/embed/8cf915f27803412cb9b2247b5cfb257a?sid=45dac67a-0f2d-4f7d-a390-25b2ce8bc

Due to a recent update, Google Maps custom markers won't work in Run or Test mode unless CanvasKit is enabled. This is expected behavior. To use custom markers effectively, enable CanvasKit from [**Advanced Web Settings**](../../../resources/projects/settings/project-setup.md#advanced-web-settings).

-
\ No newline at end of file + diff --git a/docs/ff-integrations/maps/google-maps/move-map-center-action.md b/docs/ff-integrations/maps/google-maps/move-map-center-action.md index 84c70384b..9af00f3f4 100644 --- a/docs/ff-integrations/maps/google-maps/move-map-center-action.md +++ b/docs/ff-integrations/maps/google-maps/move-map-center-action.md @@ -1,36 +1,39 @@ --- slug: /integrations/google-maps/move-map-center-action title: Move Map Center Action -description: Learn how to use the Move Map Center action in your FlutterFlow app to adjust the center of the Google Map. -tags: [Google Maps, Action, Integration] +description: >- + Learn how to use the Move Map Center action in your FlutterFlow app to adjust + the center of the Google Map. +tags: + - FlutterFlow + - Integrations + - Google Maps +last_verified: 2026-09-02 sidebar_position: 3 -keywords: [FlutterFlow, Google Maps, Action, Integration] +keywords: + - FlutterFlow + - Google Maps + - Action + - Integration --- - - # Move Map Center [Action] This action allows you to center the map on a specified location, such as setting the pickup and drop-off points. You can define the location either by directly inputting the latitude and longitude values or by using a variable. :::info[Prerequisites] -- To implement this feature, add a Google Maps widget to your page or component. +- To implement this feature, add a Google Maps widget to your page or component. [**Learn how.**](google-maps-widget.md) -- If you wish to enable users to select locations from a dropdown using FlutterFlow's PlacePicker +- If you wish to enable users to select locations from a dropdown using FlutterFlow's PlacePicker widget, you can also integrate the Place Picker widget into your map view. [**Learn more here**](place-picker-widget.md). ::: Assuming you've set up the Place Picker widget on your Google Maps widget view, let's add a button that triggers the action to move the map center, so the map centers on the newly selected location. -In our example, we've added an IconButton with a location pin icon. For the button's OnTap -action trigger, we'll add the Move Map Center action and set the LatLng to the LatLng of the +In our example, we've added an IconButton with a location pin icon. For the button's OnTap +action trigger, we'll add the Move Map Center action and set the LatLng to the LatLng of the Place Picker's selected place. You must check if the PlacePicker value (or the variable holding your new LatLng) is set before calling the Move Map Center action. -![move-map.png](imgs/move-map.png) - - - - - - +Also validate that latitude is between -90 and 90 and longitude is between -180 and 180. The action moves the existing widget's camera; it does not request location permission, geocode an address, or wait for a map widget that has not mounted. +![move-map.png](imgs/move-map.png) diff --git a/docs/ff-integrations/maps/google-maps/place-picker-widget.md b/docs/ff-integrations/maps/google-maps/place-picker-widget.md index 7ae156c37..413a49dca 100644 --- a/docs/ff-integrations/maps/google-maps/place-picker-widget.md +++ b/docs/ff-integrations/maps/google-maps/place-picker-widget.md @@ -1,12 +1,22 @@ --- slug: /integrations/google-maps/place-picker-widget title: Place Picker Widget -description: Learn how to add and configure the Place Picker widget in your FlutterFlow app. -tags: [Google Maps, Place Picker, Widget, Integration] +description: >- + Learn how to add and configure the Place Picker widget in your FlutterFlow + app. +tags: + - FlutterFlow + - Integrations + - Google Maps sidebar_position: 3 -keywords: [FlutterFlow, Google Maps, Place Picker, Widget, Integration] +keywords: + - FlutterFlow + - Google Maps + - Place Picker + - Widget + - Integration +last_verified: 2026-09-02 --- - # Place Picker Widget The `PlacePicker` widget is designed to retrieve information about places, such as establishments (e.g., buildings, parks, museums) and geographic features (e.g., roads, lakes, mountains). It provides details like name, address, city, state, country, zip code, and latitude-longitude coordinates. @@ -23,7 +33,7 @@ Here's an example from the Demo app: height: 0, width: '100%' }}> - -

\ No newline at end of file +

diff --git a/docs/ff-integrations/maps/launch-map.md b/docs/ff-integrations/maps/launch-map.md index b0bc6f7c8..e94d4057e 100644 --- a/docs/ff-integrations/maps/launch-map.md +++ b/docs/ff-integrations/maps/launch-map.md @@ -1,25 +1,30 @@ --- - title: Launch Map slug: /integrations/maps/launch-map description: Learn how to open Map app installed on your device from your FlutterFlow app. sidebar_position: 2 -tags: [Maps, Action] -keywords: [FlutterFlow, Launch Maps, Action,] +tags: + - FlutterFlow + - Integrations + - Maps +keywords: + - FlutterFlow + - Launch Maps + - Action +last_verified: 2026-09-02 --- # Launch Map Using this action, you can open the Map app installed on your device. For example, you could add this action on an event page to let users know more about the place inside the map apps like Google Maps, Apple Maps, and Waze app. -You can specify the Lat Long details or full address of any place to access the additional information such as directions, call details, timings, photos, street view, reviews, and more. +You can specify coordinates or an address. The receiving map app decides which location details and actions it displays; availability varies by provider, platform, region, and installed app.
-
-

\ No newline at end of file +

+ +## Related documentation + +See [Google Maps Widget](/integrations/google-maps/google-maps-widget) to display an interactive map inside the app instead. diff --git a/docs/ff-integrations/maps/mapbox/staticmap.md b/docs/ff-integrations/maps/mapbox/staticmap.md index 1d014d116..ab4cc910a 100644 --- a/docs/ff-integrations/maps/mapbox/staticmap.md +++ b/docs/ff-integrations/maps/mapbox/staticmap.md @@ -1,12 +1,21 @@ --- slug: /integrations/mapbox/staticmap-widget title: Static Map Widget -description: Learn how to add and configure the StaticMap (Mapbox) widget in your FlutterFlow app. -tags: [Widget, Integration] +description: >- + Learn how to add and configure the StaticMap (Mapbox) widget in your + FlutterFlow app. +tags: + - FlutterFlow + - Integrations + - Mapbox sidebar_position: 2 -keywords: [StaticMap, Mapbox, Widget, Integration] +keywords: + - StaticMap + - Mapbox + - Widget + - Integration +last_verified: 2026-09-02 --- - # Static Map Widget The StaticMap widget shows an image of the map from the [mapbox](https://www.mapbox.com/). This widget is a good choice when you want to display a location on a map without interactivity or controls such as zoom-in, zoom-out, and map scrolling. @@ -20,21 +29,24 @@ To display a map with interactivity or controls, use the [**GoogleMaps**](../goo Here's an example of how you can add the StaticMap widget to your project: 1. First, drag the **StaticMap** widget from the **Base Elements** tab (in the Widget Panel) or add it directly from the widget tree. -2. You'll need the Mapbox API key to render the map image. Get the API key by creating the [Mapbox account](https://account.mapbox.com/auth/signup/) and then return to FlutterFlow, move to the properties panel, scroll down to the Static Map section and enter the key into the **Mapbox API Key** input box. +2. You'll need a Mapbox public access token to render the map image. Create or select a token in your [Mapbox account](https://account.mapbox.com/), give it only the scopes required by the Static Images API, and apply allowed-URL restrictions for web use where applicable. Return to FlutterFlow, open the properties panel, scroll to **Static Map**, and enter the token in **Mapbox API Key**. 3. To display your location on the map, enter the **Latitude** and **Longitude** values inside the **Lat** and **Lng** input boxes. :::tip To get the lat long values for any location, open to Google Map, right-click on any place and click on the first item from the list. It should look like this `19.080045795863743`, `72.8794235725136`. ::: +:::warning[Public token, billing, and privacy] +A token embedded in a client app or image URL can be inspected. Never use a Mapbox secret token here. Monitor token usage and Mapbox billing, and rotate a token if it is abused. Coordinates and other URL parameters are sent to Mapbox; avoid exposing sensitive user locations without an appropriate privacy basis and disclosure. +::: +
-
-

\ No newline at end of file +

diff --git a/docs/ff-integrations/payments/braintree.md b/docs/ff-integrations/payments/braintree.md index 17da4e578..f98450481 100644 --- a/docs/ff-integrations/payments/braintree.md +++ b/docs/ff-integrations/payments/braintree.md @@ -2,10 +2,16 @@ slug: /integrations/payments/braintree title: Braintree description: Learn how to integrate Braintree payments in your FlutterFlow app. -tags: [Payments, Integration] -keywords: [FlutterFlow, Braintree, Payments, Integration] +tags: + - FlutterFlow + - Integrations + - Payments +keywords: + - FlutterFlow + - Braintree + - Payments + - Integration --- - # Braintree You can accept payments in your app using [Braintree](https://developer.paypal.com/braintree/docs/start/overview) (a service provided by PayPal) integration. This will also allow your users to pay directly using a credit card or using a service like PayPal, Google Pay, or Apple Pay @@ -15,9 +21,8 @@ You can accept payments in your app using [Braintree](https://developer.paypal.c paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding height: 0, width: '100%'}}> - +

@@ -28,7 +40,7 @@ There are three types of search you can add to the page: - **Firestore collection**: To search from the Firestore collection. - **Documents**: To search from the list of documents stored in a variable. -- **Strings**: To search from the list of strings stored in a variable such as app or +- **Strings**: To search from the list of strings stored in a variable such as app or page state variable. @@ -46,20 +58,18 @@ Follow the steps below to add this action to any widget. 2. On the right side, search and select the **Simple Search** action. 3. Select the **Search Type** among the **Firestore Collection**, **Documents**, and **Strings**. 4. If you select the **Firestore Collection**: - + 1. Set the **Collection** to the one that you want to search from. 2. **Select Searchable Fields** to the field that you want to perform the search on. 5. If you select the **Documents**: - - 1. Set the **Source** to the variable that holds the list of documents. For example, the + + 1. Set the **Source** to the variable that holds the list of documents. For example, the result of the query at a top-level widget such as **Page** or **Column** 2. **Select Searchable Fields** to the field that you want to perform the search on. 6. If you select the **Strings**: - - 1. Set the **Source** to the variable that holds the list of strings (e.g., app or page + + 1. Set the **Source** to the variable that holds the list of strings (e.g., app or page state variable). 7. Inside the **Search Term** section, set **Widget State > TextField** (where users enter a search term). -
- +
diff --git a/docs/ff-integrations/storage/firebase-storage/storage-library.md b/docs/ff-integrations/storage/firebase-storage/storage-library.md index 10bcd94d0..e38e2a2d4 100644 --- a/docs/ff-integrations/storage/firebase-storage/storage-library.md +++ b/docs/ff-integrations/storage/firebase-storage/storage-library.md @@ -1,14 +1,28 @@ --- slug: /integrations/firebase-storage/storage-library title: Firebase Storage Library -description: The Firebase Storage Library provides access to the files in Cloud Storage through the Firebase SDK beyond what FlutterFlow's built-in support provides. -tags: [Firebase Storage, Cloud Storage, Integration, Library] +description: >- + The Firebase Storage Library provides access to the files in Cloud Storage + through the Firebase SDK beyond what FlutterFlow's built-in support provides. +tags: + - FlutterFlow + - Integrations + - Firebase Storage sidebar_position: 2 -keywords: [FlutterFlow, Firebase Storage, Cloud Storage, Integration, Security] +keywords: + - FlutterFlow + - Firebase Storage + - Cloud Storage + - Integration + - Security +last_verified: 2026-09-02 --- +# Firebase Storage Library The [Firebase Storage Library][storage-library-item] provides access to the files in Cloud Storage through the Firebase SDK beyond what [FlutterFlow's built-in support](/concepts/file-handling) provides. +This is an imported FlutterFlow Library. Review its current Marketplace version and changes before upgrading, and test the imported actions in a non-production project. + [storage-library-item]: https://marketplace.flutterflow.io/item/Ec3NWw8sxqJ1tbriOIEE @@ -18,87 +32,89 @@ To start using this library: 1. [Import the library](/resources/projects/libraries/#importing-a-library) into your existing FlutterFlow project. 2. [Connect your FlutterFlow project to Firebase](/integrations/firebase/connect-to-firebase/) (if you haven't done so already). - The library will default to using the default bucket of your associated Firebase project. You can override this behavior by passing an explicit bucket URL to any of the actions. + The library will default to using the default bucket of your associated Firebase project. You can override this behavior by passing an explicit bucket URL to any of the actions. 3. [Use the Custom Actions](/concepts/custom-code/custom-actions/#using-a-custom-action) and Custom Functions in your Action Flows. +All client operations are constrained by the selected bucket's deployed Storage Rules. A bucket URL does not grant access to another bucket. Since February 3, 2026, Cloud Storage for Firebase requires the project to be on the Blaze plan to provision or retain bucket access, although eligible no-cost usage may still apply. + ### Custom actions -* `uploadFileToBucket` \- Upload a file to any path in any bucket that you have write access to. +* `uploadFileToBucket` \- Upload a file to any path in any bucket that you have write access to. + * **Parameters:** + * The `bucketName` (`String?`) to upload the file to. If you leave this empty, it uses the default bucket of the associated Firebase project. + * The `fullPath` (`String?`) where the file will be written to inside the bucket. If this is specified, the `prefix` parameter is ignored. + * The `uploadedFile` (`FFUploadedFile`) that is to be uploaded to Cloud Storage. This is the action output of a previous `Store media for upload` action. + * The `prefix` (folder/directory) (`String?`) where the file will be uploaded to. If `fullPath` is not specified, the action uses this parameter and the `name` of the `uploadedFile` to determine the full path where it writes the file. + * **Action result:** + * If successful, the action result is a `fileObject` containing the full path of the uploaded file. + +* `listAllFilesInBucket` \- List all files in any bucket that you have read access to. Avoid listing a large bucket root from a client; use narrow prefixes and account for Storage operation cost and memory. + * **Parameters:** + * The `bucketName` (`String?`) to list the files from. If you leave this empty, it uses the default bucket of the associated Firebase project. + * The `listType` (`StorageListType?`) of the items to list (files, directories, both). If left empty, the action will list both files and prefixes (folders/directories). + * The `prefix` (`String?`) is the `/` separated path from which to list files. If left empty, the action will list the items in the root of the storage bucket. + * **Action result:** + * If successful, the action results in a `List` of `fileObject` elements. + +* `downloadFile` \- Download the data for a file that you have read access to. This loads the file into application memory, so enforce size and content-type limits and avoid unbounded downloads. If you instead need a shareable URL, use `getDownloadUrl` and understand its access model. + * **Parameters:** + * The `bucketName` (`String?`) to download the file from. If you leave this empty, it uses the default bucket of the associated Firebase project. + * The `fullPath` (`String`) of the file whose data will be read from the bucket. + * **Action result:** + * If successful, the action result is an `FFUploadedFile` with the data of the file that was read from the bucket. + +* `getDownloadUrl` \- Get a long-lived, bearer-style download URL for a file you can currently read. Anyone who obtains the URL can fetch the object without another Storage Rules check until its download token is revoked or the object/token changes. Do not use it for confidential files; keep the object private and download through authenticated SDK access instead. + * **Parameters:** + * The `bucketName` (`String?`) that contains the file. If you leave this empty, it uses the default bucket of the associated Firebase project. + * The `fullPath` (`String`) of the file for which to get the download URL. + * **Action result:** + * If successful, the action result is a HTTP URL that allows public access to the file. + +* `getMetadataForFile` \- Get the metadata for a file in any bucket that you have read access to + * **Parameters:** + * The `bucketName` (`String?`) that contains the file. If you leave this empty, it uses the default bucket of the associated Firebase project. + * The `fullPath` (`String`) of the file for which to get the download URL. + * A**ction result:** + * If successful, the action result is a `FullMetadata` with all the metadata and custom metadata of the file. + + +* `updateMetadataForFile` \- Update the metadata for a file in any bucket that you have write access to + * **Parameters:** + * The `bucketName` (`String?`) that contains the file. If you leave this empty, it uses the default bucket of the associated Firebase project. + * The `fullPath` (`String`) of the file for which to get the download URL. + * The `metadata` (`SettableMetadata`) to write to the Cloud Storage bucket for the file. If any value is left out or empty in the metadata, it is left unmodified in Cloud Storage. + * **Action result:** + * If successful, the action result is a `FullMetadata` with all the metadata and custom metadata of the file after the update. + + +* `getPathFromUrl` \- Get the path for a file based on its (https:// or gs://) URL. This is a synchronous call, as it doesn't require any call to the server. + * **Parameters** + * The `Url` to parse. + * **Action result:** + * The action result is a `fileObject` derived from the URL. + +* `deleteFileFromBucket` \- Deletes a file from any bucket you have write access to. Confirm the exact normalized path and provide recovery or object versioning where required; this action has no application-level undo. * **Parameters:** - * The `bucketName` (`String?`) to upload the file to. If you leave this empty, it uses the default bucket of the associated Firebase project. - * The `fullPath` (`String?`) where the file will be written to inside the bucket. If this is specified, the `prefix` parameter is ignored. - * The `uploadedFile` (`FFUploadedFile`) that is to be uploaded to Cloud Storage. This is the action output of a previous `Store media for upload` action. - * The `prefix` (folder/directory) (`String?`) where the file will be uploaded to. If `fullPath` is not specified, the action uses this parameter and the `name` of the `uploadedFile` to determine the full path where it writes the file. - * **Action result:** - * If successful, the action result is a `fileObject` containing the full path of the uploaded file. - -* `listAllFilesInBucket` \- List all files in any bucket that you have read access to. - * **Parameters:** - * The `bucketName` (`String?`) to list the files from. If you leave this empty, it uses the default bucket of the associated Firebase project. - * The `listType` (`StorageListType?`) of the items to list (files, directories, both). If left empty, the action will list both files and prefixes (folders/directories). - * The `prefix` (`String?`) is the `/` separated path from which to list files. If left empty, the action will list the items in the root of the storage bucket. - * **Action result:** - * If successful, the action results in a `List` of `fileObject` elements. - -* `downloadFile` \- Download the data for a file that you have read access to. This downloads the actual data into your application code. If you instead want a public URL to the data, use `getDownloadUrl` instead. - * **Parameters:** - * The `bucketName` (`String?`) to download the file from. If you leave this empty, it uses the default bucket of the associated Firebase project. - * The `fullPath` (`String`) of the file whose data will be read from the bucket. - * **Action result:** - * If successful, the action result is an `FFUploadedFile` with the data of the file that was read from the bucket. - -* `getDownloadUrl` \- Get the download URL for a file in a bucket that you have read access to. This URL then provides public, read-only access to the file - * **Parameters:** - * The `bucketName` (`String?`) that contains the file. If you leave this empty, it uses the default bucket of the associated Firebase project. - * The `fullPath` (`String`) of the file for which to get the download URL. - * **Action result:** - * If successful, the action result is a HTTP URL that allows public access to the file. - -* `getMetadataForFile` \- Get the metadata for a file in any bucket that you have read access to - * **Parameters:** - * The `bucketName` (`String?`) that contains the file. If you leave this empty, it uses the default bucket of the associated Firebase project. - * The `fullPath` (`String`) of the file for which to get the download URL. - * A**ction result:** - * If successful, the action result is a `FullMetadata` with all the metadata and custom metadata of the file. - - -* `updateMetadataForFile` \- Update the metadata for a file in any bucket that you have write access to - * **Parameters:** - * The `bucketName` (`String?`) that contains the file. If you leave this empty, it uses the default bucket of the associated Firebase project. - * The `fullPath` (`String`) of the file for which to get the download URL. - * The `metadata` (`SettableMetadata`) to write to the Cloud Storage bucket for the file. If any value is left out or empty in the metadata, it is left unmodified in Cloud Storage. - * **Action result:** - * If successful, the action result is a `FullMetadata` with all the metadata and custom metadata of the file after the update. - - -* `getPathFromUrl` \- Get the path for a file based on its (https:// or gs://) URL. This is a synchronous call, as it doesn't require any call to the server. - * **Parameters** - * The `Url` to parse. - * **Action result:** - * The action result is a `fileObject` derived from the URL. - -* `deleteFileFromBucket` \- Deletes a file from any bucket you have write access to. - * **Parameters:** - * The `bucketName` (`String?`) that contains the file. If you leave this empty, it uses the default bucket of the associated Firebase project. - * The `fullPath` (`String`) of the file to delete from the bucket. - * **Action result:** + * The `bucketName` (`String?`) that contains the file. If you leave this empty, it uses the default bucket of the associated Firebase project. + * The `fullPath` (`String`) of the file to delete from the bucket. + * **Action result:** * If the action succeeds the file has been deleted. There is no additional information. ### Enums -* `StorageListType` is an enumeration of the types of items that the `listAllFilesInBucket` action can return. Values: - * `files`: List only the files in the specified path. - * `prefixes`: List only the prefixes in the specified path. You might more commonly refer to these as folders or directories, but since Cloud Storage doesn't actually have support for folders/directories, it uses `/` characters in the file names to emulate those and calls them prefixes. +* `StorageListType` is an enumeration of the types of items that the `listAllFilesInBucket` action can return. Values: + * `files`: List only the files in the specified path. + * `prefixes`: List only the prefixes in the specified path. You might more commonly refer to these as folders or directories, but since Cloud Storage doesn't actually have support for folders/directories, it uses `/` characters in the file names to emulate those and calls them prefixes. * `filesAndPrefixes`: List both files and prefixes in the specified path. ### Data Types -* `fileObject` \- the metadata for a file or prefix (folder/directory) in Cloud Storage. It has the following fields: - * `fullPath` (`String`) \- The full path of the file/prefix inside the storage bucket. The value does not start with a leading `/`. - * `isPrefix` (`Boolean`) \- Indicates whether the object is a file (`false`) or prefix (folder/directory) (`true`). +* `fileObject` \- the metadata for a file or prefix (folder/directory) in Cloud Storage. It has the following fields: + * `fullPath` (`String`) \- The full path of the file/prefix inside the storage bucket. The value does not start with a leading `/`. + * `isPrefix` (`Boolean`) \- Indicates whether the object is a file (`false`) or prefix (folder/directory) (`true`). * `FullMetadata` \- the full metadata of an item in a storage bucket as returned by `getMetadataForFile`, modelled after the [`FullMetadata` class in the Firebase SDK for Cloud Storage](https://pub.dev/documentation/firebase_storage/latest/firebase_storage/FullMetadata-class.html). -* `SettableMetadata` \- the settable metadata of an item in a storage bucket, as passed to a call to `updateMetadataForFile`, modelled after the [`SettableMetadata` class in the Firebase SDK for Cloud Storage](https://pub.dev/documentation/firebase_storage/latest/firebase_storage/SettableMetadata-class.html). +* `SettableMetadata` \- the settable metadata of an item in a storage bucket, as passed to a call to `updateMetadataForFile`, modelled after the [`SettableMetadata` class in the Firebase SDK for Cloud Storage](https://pub.dev/documentation/firebase_storage/latest/firebase_storage/SettableMetadata-class.html). * `KeyValuePair` \- A `String`/`String` key/value pair as used for the `customMetadata` in the `FullMetadata` and `SettableMetadata` data types. diff --git a/docs/ff-integrations/storage/firebase-storage/storage-rules.md b/docs/ff-integrations/storage/firebase-storage/storage-rules.md index f166c1293..fc14d6b5a 100644 --- a/docs/ff-integrations/storage/firebase-storage/storage-rules.md +++ b/docs/ff-integrations/storage/firebase-storage/storage-rules.md @@ -1,12 +1,22 @@ --- slug: /integrations/firebase-storage/storage-rules title: Deploy Storage Rules -description: Learn how to deploy storage rules in your FlutterFlow app to manage and secure your Firebase storage. -tags: [Firebase Storage, Storage Rules, Integration, Security] +description: >- + Learn how to deploy storage rules in your FlutterFlow app to manage and secure + your Firebase storage. +tags: + - FlutterFlow + - Integrations + - Firebase Storage sidebar_position: 1 -keywords: [FlutterFlow, Firebase Storage, Storage Rules, Integration, Security] +keywords: + - FlutterFlow + - Firebase Storage + - Storage Rules + - Integration + - Security +last_verified: 2026-09-02 --- - # Storage Rules Like [Firestore security rules](../../database/cloud-firestore/firestore-rules.md), Firebase Storage security rules control who can access files uploaded by your users in your application. @@ -14,7 +24,7 @@ Like [Firestore security rules](../../database/cloud-firestore/firestore-rules.m For example, by setting the storage rules, you can allow only authenticated users (e.g., via Email, Google Sign-in, etc.) to upload or send images. :::tip[For beginners] -If you are new to storage rules, you may want to check out this overview about [**Getting Started +If you are new to storage rules, you may want to check out this overview about [**Getting Started With Storage Rules**](https://firebase.google.com/docs/storage/security). ::: @@ -22,7 +32,7 @@ With Storage Rules**](https://firebase.google.com/docs/storage/security). To deploy the storage rules: -1. First, make sure Firebase Storage is enabled or configured in your project by visiting the +1. First, make sure Firebase Storage is enabled or configured in your project by visiting the [Firebase console](https://console.firebase.google.com/u/0/) and viewing the **Storage** tab. 2. Return to FlutterFlow, navigate to **Settings & Integrations > Project Setup > Firebase**. @@ -32,12 +42,19 @@ To deploy the storage rules: 6. Click the **Deploy** button. 7. A pop-up will open. Click **Yes** to continue and click **Deploy Now**. -
+:::warning[Review the generated rules] +**Make Users Uploads Private** depends on FlutterFlow's upload path conventions. Review the complete generated rules and test that owners, non-owners, unauthenticated users, and unexpected paths behave as intended. Authentication alone does not prove ownership. Add validation for allowed path, maximum size, content type, and any metadata your app relies on. +::: + +If you select **Manage Outside of FlutterFlow**, keep the Firebase console or a version-controlled rules file as the source of truth. A later deployment from a different source can overwrite the active rules. Test changes with the Firebase Emulator Suite or Rules Playground before production, and remember that trusted Admin SDK code bypasses Storage Rules and needs backend authorization and IAM. + +Cloud Storage for Firebase requires the Blaze plan for bucket access as of February 3, 2026. Budget alerts are notifications rather than hard spending caps. + +

:::tip[Learn more] Learn more about Firebase Storage Rules [here](https://firebase.google.com/docs/storage/security). -::: \ No newline at end of file +::: diff --git a/docs/ff-integrations/streaming/integrate-mux.md b/docs/ff-integrations/streaming/integrate-mux.md index 660708829..66ef10bbf 100644 --- a/docs/ff-integrations/streaming/integrate-mux.md +++ b/docs/ff-integrations/streaming/integrate-mux.md @@ -1,12 +1,23 @@ --- slug: /integrations/mux title: Mux Livestream -description: Learn how to get started with MuxBroadcast in your FlutterFlow app for live video broadcasting. -tags: [MuxBroadcast, Integration, Setup] +description: >- + Learn how to get started with MuxBroadcast in your FlutterFlow app for live + video broadcasting. +tags: + - FlutterFlow + - Integrations + - Mux sidebar_position: 2 -keywords: [FlutterFlow, MuxBroadcast, Integration, Setup, Mux, LiveStream] +keywords: + - FlutterFlow + - MuxBroadcast + - Integration + - Setup + - Mux + - LiveStream +last_verified: 2026-09-02 --- - # Mux Livestream Mux Livestream allows you to integrate live video streaming capabilities directly into your FlutterFlow app. It leverages Mux’s powerful streaming API, providing real-time broadcasting features. For a deeper understanding, check out [how live streaming works](https://blog.flutterflow.io/flutter-mux-live-streaming/#how-does-live-streaming-work). @@ -26,15 +37,18 @@ To get started, go to **Settings and Integrations > Integrations > Mux Livestrea Then, create a Mux account and go to **Settings > API Access Tokens**. Click **Generate new token**, choose an environment (Development or Production), check **Mux Video** with **Write** access, name the token, and generate it. Copy the **Access Token ID** and **Secret Key**, paste them into FlutterFlow, and click **Deploy**. +:::danger[Keep the Mux secret server-side] +The Secret Key grants privileged API access. Enter it only in the dedicated FlutterFlow integration so the deployed backend can use it. Never expose it in client custom code, App State, assets, Remote Config, a playback URL, or a direct client API call. Use separate development and production tokens, grant only required permissions, restrict project access, and rotate a token after suspected exposure. +::: +
-
- - +
+ +
@@ -93,16 +102,14 @@ It's important to note that while disabling Row Level Security (RLS) can be usef Here's an example of creating an "assignments" table with a [foreign key relationship](https://supabase.com/docs/guides/database/tables#joining-tables-with-foreign-keys) from `created_by` column to `public.users.id` with `on delete cascade`. This ensures that if a user is deleted from the "public.users" table, any data related to that user stored in your "assignments" table will also be deleted.
-
+
:::note -To use Supabase authentication, you must +To use Supabase authentication, you must [**create a "users" table**](../authentication/supabase-auth/initial-setup.md#1-creating-a-users-table). ::: - diff --git a/docs/generated-code/component-gen-code.md b/docs/generated-code/component-gen-code.md index 2645bac28..c4323b468 100644 --- a/docs/generated-code/component-gen-code.md +++ b/docs/generated-code/component-gen-code.md @@ -2,11 +2,21 @@ title: Component Model slug: /generated-code/component-model sidebar_position: 5 +description: >- + Learn how FlutterFlow generates widget and model files for a component, + including lifecycle actions, local state, and disposal behavior. +last_verified: 2026-09-01 +tags: + - FlutterFlow + - Generated Code +keywords: + - Component Model + - Generated Code + - FlutterFlow --- - # Generated Code: Components -Similar to a [**Page**](pages-generated-code.md), when creating a **[component](../resources/ui/components/intro-components.md)** in FlutterFlow, it automatically generates two files: a `Widget` class and a `Model` class. +Similar to a [**Page**](pages-generated-code.md), when creating a **[component](../resources/ui/components/intro-components.md)** in FlutterFlow, it automatically generates two files: a `Widget` class and a `Model` class. :::info[Prerequisites] This guide uses examples from the generated code of the **[EcommerceFlow demo app](https://bit.ly/ff-docs-demo-v2)**. To view the generated code directly, check out the **[Github repository](https://github.com/FlutterFlow/sample-apps/tree/main/ecommerce_flow)**. @@ -20,20 +30,19 @@ The lifecycle of a `ComponentModel` and its associated widget class follows the ### onComponentLoad Action: Generated Code -When you define actions for the `onComponentLoad` action trigger of a component, these actions are added inside an `addPostFrameCallback` method within the page's `initState` method. This ensures that the actions are executed only after the initial widget tree is built. +When you define actions for the `onComponentLoad` action trigger of a component, those actions are added inside a `SchedulerBinding.instance.addPostFrameCallback` callback in the component widget's `initState` method. This schedules them after the first frame. ```js @override void initState() { super.initState(); - _model = createModel(context, () => ProductListPageModel()); + _model = createModel(context, () => ProductCardModel()); // On component load action. SchedulerBinding.instance.addPostFrameCallback((_) async { await _model.updateTotalCost(context); safeSetState(() {}); }); - + } ``` - diff --git a/docs/generated-code/custom-data-type-gen.md b/docs/generated-code/custom-data-type-gen.md index c822632ef..ee0db2a45 100644 --- a/docs/generated-code/custom-data-type-gen.md +++ b/docs/generated-code/custom-data-type-gen.md @@ -1,9 +1,19 @@ --- -title: Custom Data Types +title: 'Custom Data Types: Generated Code' slug: /generated-code/custom-data-types sidebar_position: 2 +description: >- + Learn how FlutterFlow generates a Struct class, field accessors, serialization, + and helper methods for each Custom Data Type. +last_verified: 2026-09-01 +tags: + - FlutterFlow + - Generated Code +keywords: + - 'Custom Data Types: Generated Code' + - Custom Data Types + - Generated Code --- - # DataTypeStruct class :::info[Prerequisites] @@ -11,6 +21,12 @@ This guide uses example of the generated code of the **[EcommerceFlow demo app]( ::: -When you create a custom data type in the FlutterFlow editor, a corresponding class is generated in the code to act as a structured container for your data, similar to a `Struct`. This class includes simple getters and setters for each field. For example, if your data type in FlutterFlow is named "Product", the generated class will be named `ProductStruct` and can be found in the `product_struct.dart` file. +When you create a custom data type in the FlutterFlow editor, FlutterFlow generates a corresponding Struct class under `lib/backend/schema/structs/`. For example, a data type named "Product" generates `ProductStruct` in `product_struct.dart`. + +The generated class includes a constructor, typed field getters and setters, `has()` helpers, map and serializable-map conversion, equality support, and field-specific helpers where applicable. Numeric fields can receive increment helpers, while lists and nested Structs can receive update helpers. Firestore-specific conversion code is included only when the project uses Firestore. + +![custom-data-type-gen-class.png](imgs/custom-data-type-gen-class.png) + +## Related documentation -![custom-data-type-gen-class.png](imgs/custom-data-type-gen-class.png) \ No newline at end of file +See [Component Model](/generated-code/component-model) for a related FlutterFlow workflow. diff --git a/docs/generated-code/directory-structure.md b/docs/generated-code/directory-structure.md index b94a59037..319a939cb 100644 --- a/docs/generated-code/directory-structure.md +++ b/docs/generated-code/directory-structure.md @@ -1,9 +1,19 @@ --- -title: Directory Structure +title: Directory Structure slug: /generated-code/project-structure sidebar_position: 1 +description: >- + Understand the folders and feature-dependent files in an exported FlutterFlow + project, from page models to backend and custom-code modules. +last_verified: 2026-09-01 +tags: + - FlutterFlow + - Generated Code +keywords: + - Directory Structure + - Project Structure + - Generated Code --- - # Directory Structure :::info[Prerequisites] @@ -14,6 +24,8 @@ When you download the code generated by FlutterFlow, you'll notice many addition ## Folder Structure +The following is an illustrative feature-rich project. FlutterFlow emits feature-specific folders and files only when the project uses them, so a smaller project will not contain every entry shown here. + ``` assets/ lib/ @@ -40,7 +52,7 @@ lib/ - util/ - firestore_util.dart - schema_util.dart - - carts_record.dart + - carts_record.dart - ... - index.dart - backend.dart @@ -106,15 +118,15 @@ The `backend/` directory is responsible for handling all the backend logic and i - **cloud_functions/**: This directory is used to store functions that interact with cloud-based services, such as Firebase Cloud Functions. These functions are used for operations that need to be performed on the server side, such as complex calculations, data processing, or sending notifications. - **schema/**: The schema/ directory is crucial for defining the structure of data used throughout your app. It contains the following subdirectories and files: - - **enums/:** Stores enumeration types used across the app. - - **structs/:** These are used to represent custom data types like `Address` or `Cart`. + - **enums/:** Stores enumeration types used across the app. + - **structs/:** These are used to represent custom data types like `Address` or `Cart`. - **util/:** Contains utility functions like `firestore_util.dart` and `schema_util.dart`. ### custom_code/ Custom Actions and Custom Widgets created by the developer are stored in this folder, in their respective subdirectories: `custom_code/actions` and `custom_code/widgets`. ### flutter_flow/ -This directory is generated by FlutterFlow and contains various utility files that support the app's operation, such as custom functions, generated themes, navigation and more. +This directory is generated by FlutterFlow and contains various utility files that support the app's operation, such as custom functions, generated themes, navigation and more. ### app_constants.dart This class is used to store constant values that are used throughout the application. diff --git a/docs/generated-code/ff-app-state.md b/docs/generated-code/ff-app-state.md index ab792043c..d5120c61b 100644 --- a/docs/generated-code/ff-app-state.md +++ b/docs/generated-code/ff-app-state.md @@ -1,8 +1,18 @@ --- title: FFAppState sidebar_position: 4 +description: >- + Learn how FFAppState is represented in FlutterFlow generated code and where it + fits in an exported app. +last_verified: 2026-09-01 +tags: + - FlutterFlow + - Generated Code +keywords: + - FFAppState + - Ff App State + - Generated Code --- - # FFAppState :::info[Prerequisites] @@ -45,20 +55,20 @@ class FFAppState extends ChangeNotifier { } ``` -The `_enableDarkMode` is an App State variable created by developer that creates its own corresponding getter and setter. +The `_enableDarkMode` is an App State variable created by developer that creates its own corresponding getter and setter. ## Rebuild on Updating AppState When updating an `AppState` variable from the Action Flow Editor, you will be presented with several **[update type](../resources/data-representation/app-state.md#update-type)** options such as **Rebuild All Pages**, **Rebuild Current Page**, and **No Rebuild** in the Action Settings. Let's see how the generated code changes when these options are selected. ### Rebuild Current Page -When a developer chooses to update App State with the update type set to **Rebuild Current Page**, the corresponding `setter` is called. Immediately after, `setState(() {});` is invoked, which updates only the current page. +When a developer chooses to update App State with the update type set to **Rebuild Current Page**, the corresponding setter is called. Immediately after, `safeSetState(() {});` is invoked, which updates only the current page when its State object is still mounted. Here's an example of the generated code when we update the App State `enableDarkMode` in the `onInitialization` action trigger of the `ProductListPage`. ```js SchedulerBinding.instance.addPostFrameCallback((_) async { FFAppState().enableDarkMode = !(FFAppState().enableDarkMode ?? true); - setState(() {}); + safeSetState(() {}); }); ``` @@ -97,7 +107,7 @@ Widget build(BuildContext context) { By using `context.watch()`, the widget effectively subscribes to any changes in the `FFAppState` class. Whenever there's a change in the `FFAppState` object, this widget automatically rebuilds to reflect those changes. This ensures that your widget always displays the most current data and state of the app, maintaining an up-to-date and responsive user interface. ## Managing AppState\ -When you add an App State variable of `List` type in FlutterFlow, several utility functions are automatically generated to help you manage this list. These functions include a getter, a setter, and methods for adding, removing, and updating items in the list. This setup ensures that you can easily interact with the list while keeping the app state consistent and responsive. Below is an explanation of these generated functions using the specific example of a LatLngList. +When you add an App State variable of `List` type in FlutterFlow, utility methods are generated for adding, removing, inserting, and updating items. The following `LoggableList` example reflects debug-enabled generated code; production exports may use a regular `List` while retaining the same public state operations. ```js diff --git a/docs/generated-code/flutterflow-model.md b/docs/generated-code/flutterflow-model.md index de0b875de..80a0fd2e3 100644 --- a/docs/generated-code/flutterflow-model.md +++ b/docs/generated-code/flutterflow-model.md @@ -2,11 +2,22 @@ title: FlutterFlow Model slug: /generated-code/flutterflow-model sidebar_position: 4 +description: >- + The class is an abstract class used in FlutterFlow to provide a unified and + extensible structure for managing state and behavior of widgets (both pages + and components). +last_verified: 2026-09-01 +tags: + - FlutterFlow + - Generated Code +keywords: + - FlutterFlow Model + - Generated Code + - FlutterFlow --- - # FlutterFlow Model -The `FlutterFlowModel` class is an abstract class used in FlutterFlow to provide a unified and extensible structure for managing state and behavior of widgets (both pages and components). It encapsulates **initialization, state management,** and **disposal** logic, making it easier to handle the lifecycle of widgets and their models. +The `FlutterFlowModel` class is an abstract class used in FlutterFlow to provide a unified and extensible structure for managing state and behavior of widgets (both pages and components). It encapsulates **initialization, state management,** and **disposal** logic, making it easier to handle the lifecycle of widgets and their models. FlutterFlow automatically generates the `flutter_flow_model.dart` file, which contains the `FlutterFlowModel` class and utility methods like `wrapWithModel()` and `createModel()`. @@ -42,7 +53,7 @@ abstract class FlutterFlowModel { ``` -## Widget & Context references +## Widget & Context references Provides references to the associated widget and its `BuildContext`. @@ -88,7 +99,7 @@ Allows the model to notify the associated widget or parent component/page when u // Function to call when the model receives an update. VoidCallback _updateCallback = () {}; void onUpdate() => updateOnChange ? _updateCallback() : () {}; - + FlutterFlowModel setOnUpdate({ bool updateOnChange = false, required VoidCallback onUpdate, @@ -96,7 +107,7 @@ Allows the model to notify the associated widget or parent component/page when u this .._updateCallback = onUpdate ..updateOnChange = updateOnChange; - + // Update the containing page when this model received an update. void updatePage(VoidCallback callback) { callback(); @@ -104,6 +115,6 @@ Allows the model to notify the associated widget or parent component/page when u } ``` -## wrapWithModel() +## wrapWithModel() -The `wrapWithModel()` method in FlutterFlow links a model to a widget and its child widgets, allowing them to access and manage state. It wraps the widget with a Provider, making the model available throughout the widget tree. \ No newline at end of file +The `wrapWithModel()` method in FlutterFlow links a model to a widget and its child widgets, allowing them to access and manage state. It wraps the widget with a Provider, making the model available throughout the widget tree. diff --git a/docs/generated-code/pages-generated-code.md b/docs/generated-code/pages-generated-code.md index d1fd5c93b..84a9a31c1 100644 --- a/docs/generated-code/pages-generated-code.md +++ b/docs/generated-code/pages-generated-code.md @@ -2,11 +2,21 @@ title: Page Model slug: /generated-code/page-model sidebar_position: 5 +description: >- + Learn how FlutterFlow generates widget and model files for a page, including + local state, child models, lifecycle actions, and disposal. +last_verified: 2026-09-01 +tags: + - FlutterFlow + - Generated Code +keywords: + - Page Model + - Generated Code + - FlutterFlow --- - # Generated Code: Pages -When you create a new Page in FlutterFlow, it automatically generates two files: a `Widget` class and a `Model` class. So if the name of the page you created is called **ProductListPage**, FlutterFlow generation backend will automatically create **ProductListPageWidget** class and **ProductListPageModel** class. +When you create a new Page in FlutterFlow, it automatically generates two files: a `Widget` class and a `Model` class. So if the name of the page you created is called **ProductListPage**, FlutterFlow generation backend will automatically create **ProductListPageWidget** class and **ProductListPageModel** class. :::info[Prerequisites] This guide uses examples from the generated code of the **[EcommerceFlow demo app](https://bit.ly/ff-docs-demo-v2)**. To view the generated code directly, check out the **[Github repository](https://github.com/FlutterFlow/sample-apps/tree/main/ecommerce_flow)**. @@ -16,20 +26,20 @@ This guide uses examples from the generated code of the **[EcommerceFlow demo ap The `PageModel` classes are responsible for managing the state of individual pages and initializing the components used in these Pages. These classes extend the `FlutterFlowModel` class, which provides a consistent structure and shared functionality across all page models. -The following diagram shows how FlutterFlow generates the model and widget class when you create a new Page in FlutterFlow: +The following diagram shows how FlutterFlow generates the model and widget class when you create a new Page in FlutterFlow: ![page-generation-initial.png](imgs/page-generation-initial.png) :::tip[FlutterFlow Model] -To learn more about the utility classes and methods that FlutterFlow generates for all pages & components, see [**the FlutterFlowModel document**](flutterflow-model.md). +To learn more about the utility classes and methods that FlutterFlow generates for all pages & components, see [**the FlutterFlowModel document**](flutterflow-model.md). ::: #### Managing Local State -A `PageModel` class typically holds local state fields specific to the page, which correspond to the **[Page State variables](../resources/ui/pages/page-lifecycle.md#page-state)**. +A `PageModel` class typically holds local state fields specific to the page, which correspond to the **[Page State variables](../resources/ui/pages/page-lifecycle.md#page-state)**. -For example, in the ProductListPage, user may create a Page State variable called `searchString`. Correspondingly, in the `product_list_page_model.dart` [file](https://github.com/FlutterFlow/sample-apps/blob/main/ecommerce_flow/lib/product/product_list_page/product_list_page_model.dart) (which is the `Model` file for the `ProductListPage`), the corresponding state field would be `_searchString`. This private field stores the current search string and includes a getter and setter to manage its value while logging any changes. +For example, a `ProductListPage` can define a Page State variable named `searchString` in `product_list_page_model.dart`. In debug-enabled generated code, the field can use a private backing field with getter and setter logging as shown below. Production exports may emit a simpler public field while preserving the same Page State behavior. ```js String? _searchString; @@ -65,7 +75,7 @@ The `PageModel` class is also responsible for initializing the models of compone @override void initState(BuildContext context) { cartCounterModel = createModel(context, () => CartCounterModel()..parentModel = this); - + } ``` :::info @@ -117,7 +127,7 @@ class _ProductListPageWidgetState extends State { @override void initState() { super.initState(); - _model = createModel(context, () => ProductDetailPageModel()); + _model = createModel(context, () => ProductListPageModel()); } @@ -175,10 +185,10 @@ When you define actions for the `onPageLoad` action trigger of a Page, these act safeSetState(() {}); ... // more actions }); - + } ``` :::tip[safe Set State] The `safeSetState` method is a custom implementation built on top of Flutter's `setState` method. It ensures that `setState` is only called when the widget is currently mounted, preventing potential runtime errors. -::: \ No newline at end of file +::: diff --git a/docs/generated-code/state-mgmt-gen-code.md b/docs/generated-code/state-mgmt-gen-code.md index c8f202373..51e2eae50 100644 --- a/docs/generated-code/state-mgmt-gen-code.md +++ b/docs/generated-code/state-mgmt-gen-code.md @@ -2,12 +2,18 @@ slug: /generated-code/state-management title: FlutterFlow State Management description: Learn about the state management used in FlutterFlow's generated code. -tags: [Generated Code, Concepts, State Management] +last_verified: 2026-09-01 +tags: + - FlutterFlow + - Generated Code toc_max_heading_level: 4 sidebar_position: 3 -keywords: [FlutterFlow, Generated Code, State Management, Concepts] +keywords: + - FlutterFlow + - Generated Code + - State Management + - Concepts --- - # FlutterFlow State Management :::warning[Correct topic?] @@ -57,22 +63,13 @@ Variables required across multiple pages of the app, such as a username, should All defined variables within the app state are components of the `FFAppState` class, which functions as a ChangeNotifier. This means listeners can subscribe and receive notifications when any changes occur. -On each page that requires access to app state variables, the method ```context.watch()``` is called to initialize a listener for that page. This ```watch()``` method, provided by the Provider package, facilitates access to inherited widgets and acts as an effective wrapper. +On each page or component that must rebuild when App State changes, generated code calls `context.watch()`. This `watch()` method is provided by the Provider package and subscribes the widget to `FFAppState` notifications. ## Persisting App State When an app state variable is created, selecting the "Persisted" option enables FlutterFlow to save it on the device using the [**Shared Preferences**](https://pub.dev/packages/shared_preferences) package. This ensures the variable remains available even after the app is restarted, making it ideal for persisting settings such as login status or a user's choice between light and dark modes. -If the "**Secure Persisted Fields**" option is enabled in the app state settings, FlutterFlow utilizes the [**Flutter Secure Storage**](https://pub.dev/packages/flutter_secure_storage) package to encrypt the data. - -:::tip[Platform Differences] -If the platform is **Android**, then `flutter_secure_storage` stores data in [**`encryptedSharedPreference`**](https://developer.android.com/reference/androidx/security/crypto/EncryptedSharedPreferences), which are shared preferences that encrypt keys and values. It handles [**AES Encryption**](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) to generate a secret key encrypted with [**RSA**](https://en.wikipedia.org/wiki/RSA_(cryptosystem)) and stored in [**KeyStore**](https://developer.android.com/reference/java/security/KeyStore). - -For the **iOS** platform, it uses the [**KeyChain**](https://developer.apple.com/documentation/security/keychain_services) which is an iOS-specific secure storage used to store and access cryptographic keys only in your app. - -In the case of the **Web**, it uses the [**Web Cryptography**](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API) (Web Crypto) API. -::: - +If the **Secure Persisted Fields** option is enabled in App State settings, FlutterFlow uses the [**Flutter Secure Storage**](https://pub.dev/packages/flutter_secure_storage) package instead of Shared Preferences. The package delegates storage to platform-appropriate secure storage; consult its current platform documentation for implementation and availability details. ## Global State @@ -91,4 +88,4 @@ Global properties are retrieved through methods defined in `flutter_flow_utils.d ## Constants -For values that do not change throughout the app, such as API keys or environment flags, we utilize the `FFAppConstants` class, which can be found in `lib/app_constants.dart`. This is an abstract class, meaning it cannot be directly instantiated. Instead, it serves as a namespace for static constants, allowing these values to be organized and accessed consistently across the application. \ No newline at end of file +For values that do not change throughout the app, such as API keys or environment flags, we utilize the `FFAppConstants` class, which can be found in `lib/app_constants.dart`. This is an abstract class, meaning it cannot be directly instantiated. Instead, it serves as a namespace for static constants, allowing these values to be organized and accessed consistently across the application. diff --git a/docs/index.md b/docs/index.md index e7c4b1093..f26a1f5aa 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,12 +1,23 @@ --- -title: Getting Started +title: Getting Started with FlutterFlow custom_edit_url: null showLastUpdateTime: false hide_title: true slug: / hide_table_of_contents: false +description: >- + FlutterFlow is a visual development environment that lets you build mobile, + web, and desktop apps incredibly fast, without sacrificing on app quality or + features. +tags: + - FlutterFlow + - Getting Started +keywords: + - Getting Started with FlutterFlow + - FlutterFlow + - Getting Started with FlutterFlow guide +last_verified: 2026-09-02 --- - import InfoCard from '@site/src/components/InfoCard'; import InfoCards from '@site/src/components/InfoCards'; import FlutterFlowDocsLogo from '@site/src/components/FlutterFlowDocsLogo'; @@ -22,22 +33,22 @@ import BranchIcon from '@site/static/icons/branch_New.png'; # Getting Started with FlutterFlow -FlutterFlow is a visual development environment that lets you build mobile, web, and desktop apps incredibly fast, without sacrificing on app quality or features. +FlutterFlow is a visual development environment that lets you build mobile, web, and desktop apps incredibly fast, without sacrificing on app quality or features. - - @@ -53,18 +64,18 @@ FlutterFlow is a visual development environment that lets you build mobile, web, - - @@ -86,17 +97,17 @@ FlutterFlow is a visual development environment that lets you build mobile, web, Essential guidelines and recommendations for building robust FlutterFlow applications. Discover security best practices and performance optimization techniques to ensure your apps are production-ready, scalable, and maintainable. - - - - - + ### Additional Tools -Discover additional tools and references to enhance your FlutterFlow development experience: +Discover additional tools and references to enhance your FlutterFlow development experience: - - @@ -155,5 +166,5 @@ If you're still experiencing issues or need additional help, here are some resou - **[Community Forum](https://community.flutterflow.io)** - Ask questions and get help from the community - **[Reddit Community](https://www.reddit.com/r/FlutterFlow/)** - Join discussions on Reddit - **[Documentation Bug](https://github.com/FlutterFlow/flutterflow-documentation/issues)** - Report documentation issues -- **[Contribute to Documentation](https://github.com/FlutterFlow/flutterflow-documentation?tab=readme-ov-file#how-to-contribute)** - Contribution guidelines for contributing to the FlutterFlow documentation site. -- **[FlutterFlow Support](mailto:support@flutterflow.io)** - Get direct support from the FlutterFlow support team. \ No newline at end of file +- **[Contribute to Documentation](https://github.com/FlutterFlow/flutterflow-documentation?tab=readme-ov-file#how-to-contribute)** - Contribution guidelines for contributing to the FlutterFlow documentation site. +- **[FlutterFlow Support](mailto:support@flutterflow.io)** - Get direct support from the FlutterFlow support team. diff --git a/docs/intro/before-you-begin/app-architecture.md b/docs/intro/before-you-begin/app-architecture.md index a43af2a7d..dc015ba11 100644 --- a/docs/intro/before-you-begin/app-architecture.md +++ b/docs/intro/before-you-begin/app-architecture.md @@ -1,19 +1,29 @@ --- slug: /before-you-begin/app-architecture title: App Architecture +description: >- + Before you jump in and start using FlutterFlow, it's helpful to have an idea + of how app development works more broadly. +tags: + - FlutterFlow + - Getting Started +keywords: + - App Architecture + - Before You Begin + - FlutterFlow +last_verified: 2026-09-02 --- - # App Development -Before you jump in and start using FlutterFlow, it's helpful to have an idea of how app development works more broadly. +Before you jump in and start using FlutterFlow, it's helpful to have an idea of how app development works more broadly. -Traditionally, developing an app required writing a lot of code. You can think of code as a set of instructions for the computer, or device, executing the code. +Traditionally, developing an app required writing a lot of code. You can think of code as a set of instructions for the computer, or device, executing the code. -The codebase is usually divided up into two pieces: instructions for the frontend, and instructions for the backend. +The codebase is usually divided up into two pieces: instructions for the frontend, and instructions for the backend. -# Frontend vs Backend +## Frontend vs Backend -Frontend development deals with creating the parts of an application that users interact with directly. +Frontend development deals with creating the parts of an application that users interact with directly. This includes: - Defining the visual pieces of your app, like text or buttons @@ -27,19 +37,19 @@ Backend usually refers to more complex logic and data storage. This includes: - Defining business logic, either by writing code or using a low-code tool -The interaction between frontend and backend often occurs through APIs (Application Programming Interfaces). -In most cases, the backend exposes endpoints for the frontend to send requests to. -The backend handles the request, and sends some data back in response - which the frontend can use to change its visual appearance. +The interaction between frontend and backend often occurs through APIs (Application Programming Interfaces). +In most cases, the backend exposes endpoints for the frontend to send requests to. +The backend handles the request, and sends some data back in response - which the frontend can use to change its visual appearance. -# Where does the code execute? +## Code execution locations Backend code runs on a server, which could be located in a data center or hosted on a cloud platform like AWS, Google Cloud, or Azure. The server is responsible for handling requests, processing data, and sending responses back to the frontend. Frontend code runs on the user's device. This could be a web browser for web applications or the operating system for mobile applications. The frontend code is responsible for displaying the user interface and handling user interactions. -# Frontend architecture +## Frontend architecture When it comes to developing the frontend of your application, there are several key architectural patterns and best practices to consider. These include: @@ -50,3 +60,7 @@ When it comes to developing the frontend of your application, there are several By understanding these concepts and implementing best practices, you can create robust and user-friendly applications with FlutterFlow. + +## Related documentation + +See [Setting Up FlutterFlow](/before-you-begin/setup-flutterflow) for a related FlutterFlow workflow. diff --git a/docs/intro/before-you-begin/setting-up-flutterflow.md b/docs/intro/before-you-begin/setting-up-flutterflow.md index e3455aaf4..acf622947 100644 --- a/docs/intro/before-you-begin/setting-up-flutterflow.md +++ b/docs/intro/before-you-begin/setting-up-flutterflow.md @@ -1,13 +1,21 @@ --- slug: /before-you-begin/setup-flutterflow title: Setting Up FlutterFlow -description: Ensure you meet system requirements and grasp technical concepts for smooth building in FlutterFlow. +description: >- + Ensure you meet system requirements and grasp technical concepts for smooth + building in FlutterFlow. +tags: + - FlutterFlow + - Getting Started +keywords: + - Setting Up FlutterFlow + - Setup Flutterflow + - Before You Begin +last_verified: 2026-09-02 --- - - # Create an account -Create your free account to get started with FlutterFlow. After you've set up your account, you'll be able to create as many projects as you like. +Create a free account to get started with FlutterFlow. The number of editable projects and available features depends on your current plan; see [Plans & Pricing](../../accounts-billing/plan-pricing.md) before relying on a specific limit. You can [**sign up**](https://app.flutterflow.io/create-account) via Apple, Google, or Github. @@ -15,19 +23,20 @@ You can [**sign up**](https://app.flutterflow.io/create-account) via Apple, Goog The FlutterFlow application can be accessed from your browser or installed as a desktop app. -### General recommendations: -- Use a screen that is at least **1280 x 1024** +### General recommendations +- Use a screen that is at least **1280 x 1024** -### Browser recommendations: -- FlutterFlow works best on **Google Chrome** +### Browser recommendations +- FlutterFlow works best on **Google Chrome** - We recommend keeping your browser up-to-date, specifically within the latest two versions - You should allow pop-up and redirects and ClipBoard from _app.flutterflow.io_. -### Desktop recommendations: -- **macOS**: While FlutterFlow should work on 10.13 or higher, we recommend using 13 or higher -- **Windows**: While FlutterFlow should work on 7 or higher, we recommend using 10 or higher +### Desktop recommendations + +- Download the macOS or Windows app only from the official [FlutterFlow Desktop Apps](https://flutterflow.io/desktop) page. +- Keep the desktop app and operating system updated. Confirm current operating-system requirements on the download page before installation. :::info Some Windows users may experience a crash. To fix this, install the [**Microsoft Visual C++ 2015–2022 Redistributable (both x64 and x86)**](https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170) from the official Microsoft site. @@ -35,10 +44,7 @@ Some Windows users may experience a crash. To fix this, install the [**Microsoft For details on target platform system requirements, please see the [Flutter documentation](https://docs.flutter.dev/reference/supported-platforms). -### Desktop vs Web: -We recommend using the desktop application for improved performance and access to features like [**local run**](../../testing-deployment-publishing/running-your-app/local-run.md). - -However, our desktop applications are currently in a preview phase, which may result in some instability. - - +### Desktop vs Web +We recommend using the desktop application for improved performance and access to features like [**local run**](../../testing-deployment-publishing/running-your-app/local-run.md). +Use the web app when you do not need desktop-only capabilities. Browser permissions, local toolchains, and device access can make behavior differ between the two surfaces. diff --git a/docs/intro/ff-ui/builder.md b/docs/intro/ff-ui/builder.md index 34732f67a..781da9bc0 100644 --- a/docs/intro/ff-ui/builder.md +++ b/docs/intro/ff-ui/builder.md @@ -1,16 +1,23 @@ --- slug: /flutterflow-ui/builder title: App Builder -description: Explore the App Builder in FlutterFlow, featuring a comprehensive interface with - four main sections-Navigation Menu, Toolbar, Canvas, and Properties Panel. -tags: [App Builder, FlutterFlow, UI, Design] +description: >- + Explore the App Builder in FlutterFlow, featuring a comprehensive interface + with four main sections-Navigation Menu, Toolbar, Canvas, and Properties + Panel. +tags: + - FlutterFlow + - FlutterFlow UI sidebar_position: 1 -keywords: [App Builder, FlutterFlow, UI, Design] +keywords: + - App Builder + - FlutterFlow + - UI + - Design --- - # App Builder -On opening the project, you'll see the App Builder, which consists of four main sections: +On opening the project, you'll see the App Builder, which consists of four main sections: [Navigation Menu](#navigation-menu), [Toolbar](#toolbar), [Canvas](#canvas-area), and [Properties Panel](#properties-panel). ![navigation-menu.avif](imgs/navigation-menu.avif) @@ -49,10 +56,10 @@ In the [Canvas Area](canvas.md), you can see a preview of a device's screen and ## Properties Panel -The Properties Panel lets you modify both the visual appearance and interactive behavior of UI +The Properties Panel lets you modify both the visual appearance and interactive behavior of UI elements on the canvas. It allows you to add [Actions](../../resources/control-flow/functions/action-flow-editor.md), set up a [Backend Query](../../resources/control-flow/backend-logic/backend-query/backend-query.md), add [Animations](../../ff-concepts/animations/animations.md) and more. The Properties Panel will vary slightly depending on the entity you have selected. To explore the details of each Properties Panel, click on the following: - **[Page Properties](../../resources/ui/pages/pages-properties.md)** (when you have selected a Page) -- **[Widget Properties](../../resources/ui/widgets/widget-properties.md)** (when you have selected any widget, including built-in components) \ No newline at end of file +- **[Widget Properties](../../resources/ui/widgets/widget-properties.md)** (when you have selected any widget, including built-in components) diff --git a/docs/intro/ff-ui/canvas.md b/docs/intro/ff-ui/canvas.md index 4a1d1cded..655cd8c5f 100644 --- a/docs/intro/ff-ui/canvas.md +++ b/docs/intro/ff-ui/canvas.md @@ -1,12 +1,19 @@ --- slug: /flutterflow-ui/canvas title: Canvas -description: Dive into the versatile Canvas in FlutterFlow, where you can effortlessly design and preview your app’s interface. -tags: [Canvas, FlutterFlow, UI, Design] +description: >- + Dive into the versatile Canvas in FlutterFlow, where you can effortlessly + design and preview your app’s interface. +tags: + - FlutterFlow + - FlutterFlow UI sidebar_position: 2 -keywords: [Canvas, FlutterFlow, UI, Design] +keywords: + - Canvas + - FlutterFlow + - UI + - Design --- - # Canvas The Canvas shows the selected device screen, such as mobile, tablet, web, or desktop. It allows you to add widgets via drag-and-drop. You can select, move, and position widgets anywhere on the Canvas. @@ -17,7 +24,7 @@ The Canvas also includes zoom controls, light and dark previews, multi-language ## Show or Hide Navigation Menu -From here, you can open or close the +From here, you can open or close the [Navigation Menu](../../../docs/intro/ff-ui/builder.md#navigation-menu). ## Zoom Controls @@ -41,7 +48,7 @@ You can also set a custom preview size by clicking the current size box, enterin paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding height: 0, width: '100%'}}> - +

@@ -84,15 +94,14 @@ In the above demo, a `GET` API call is defined to fetch users' data from [REQ  A demo of using a dynamic URL in a GET request is as follows: -
+

To add such an API call: -1. Replace the hard-coded value with a meaningful name inside the brackets (e.g., from `https://reqres.in/api/users/2`to `https://reqres.in/api/users/[user_id]`). -2. And then, [create a new variable](rest-api.md#creating-variables) with the same name you provided inside the brackets. +1. Replace the hard-coded value with a meaningful name inside square brackets (for example, change `https://example.com/api/users/2` to `https://example.com/api/users/[user_id]`). +2. [Create a variable](rest-api.md#creating-variables) with the same name. The DELETE API Call can also be defined similarly; just make sure you select the **Method Type** as ***DELETE***. @@ -108,8 +117,7 @@ If you have selected **POST request**, follow the steps below: After making any changes, you must save the API call. ::: -
+

@@ -121,10 +129,6 @@ The PUT and PATCH API calls can be defined similarly; make sure you enter a vali You can create a group of API calls that share the same base URL. Grouping the API calls helps you add all request headers (e.g., auth token) at once, and they will be automatically added for all the API calls inside the group. -:::warning -For [**private APIs**](rest-api.md#private-api-calls), headers defined within the group will not be automatically included. You'll need to manually add headers for APIs marked as private. -::: - To create the API Group: 1. Click on the **+** button (top left side) and select the **Create API Group**. @@ -135,8 +139,7 @@ To create the API Group: 6. Open the newly created API group, and click on the **+ Add API Call**. 7. Add the API call as you would normally do. **Note**: Inside the API endpoint, enter the URL portion that starts after the base URL. -
+

@@ -162,8 +165,7 @@ To import API call definitions: Here's an example of importing API calls in bulk, taken from [here](https://editor.swagger.io/). -
+

## Testing API calls @@ -175,11 +177,14 @@ To test the API call along with its response, follow the steps below: 1. Select an API call you have already created or are currently defining, and go to the **Response & Test** tab. 2. On the left side, you will see the **Variables** section, where you can enter the values for the variables defined for your API call. 3. On the right, the **Preview** section lets you check the API URL, request headers, request body, and response. In the **Test Response** tab, you can view the full API response, including both the JSON format and raw body text, as well as the response header. -4. Click **Test API Call** to trigger the API call. You'll notice that the status of the GET request is displayed, and if it's successful (status code `200`), the result returned from that request will also be displayed below. +4. Click **Test API Call** to send the request. The response shows the HTTP status, headers, JSON representation when available, and raw body. FlutterFlow treats status codes from `200` through `299` as successful. 5. Any value of the JSON result can be accessed by [defining the JSON path](rest-api.md#json-path). -
+:::warning +**Test API Call sends a real request.** A POST, PUT, PATCH, or DELETE test can create, change, or delete data. Use test credentials and a non-production endpoint or payload whenever the operation has side effects. Never paste a production secret into a client-visible variable. +::: + +

@@ -190,8 +195,7 @@ The demo below shows the testing of creating a new user using a POST request. Th The testing of `PUT` and `PATCH` requests would also be similar to this. ::: -
+

@@ -217,18 +221,17 @@ Go to your project and follow the steps below to define the Action to any widget 1. Select the **Group or Call Name** from the dropdown. 2. Optional: If your API call requires variables (e.g., auth token, query parameters, user id, etc.), pass their value by clicking on the **+ Variable** button. 3. The **Action Output Variable Name** helps you retrieve the response of an API call. By default, we set it to any random name. However, you can change it to a meaningful name if you wish to. (e.g., loginResponse). - 4. You can add a conditional action that checks if the API call is succeeded. - 5. If the API call is succeeded, all actions under the TRUE path will be executed. For example, [navigate](../../../../ff-concepts/navigation-routing/page-navigation.md#navigate-to-action) to the home page if the login is successful. - 6. If the API call is failed, all actions under the FALSE path will be executed. For example, [showing a snackbar](../../../ui/pages/page-elements.md#snackbar) if the login is unsuccessful. + 4. Add a conditional action that checks the API response's **Succeeded** value. + 5. Under the TRUE path, handle successful `2xx` responses—for example, [navigate](../../../../ff-concepts/navigation-routing/page-navigation.md#navigate-to-action) after a successful login. + 6. Under the FALSE path, handle non-`2xx` responses—for example, [show a Snackbar](../../../ui/pages/page-elements.md#snackbar). Also design for timeouts and malformed response data.
-
-

\ No newline at end of file +

+ +## Verify an API definition + +Test representative valid, invalid, unauthenticated, non-`2xx`, empty, malformed, and slow responses. Confirm URL and query substitution, headers, body encoding, response types, JSON paths, and every success/error branch. For grouped calls, verify the shared base URL, variables, and headers on more than one endpoint. diff --git a/docs/resources/control-flow/backend-logic/api/rest-api.md b/docs/resources/control-flow/backend-logic/api/rest-api.md index 337b00a2f..a4045f34c 100644 --- a/docs/resources/control-flow/backend-logic/api/rest-api.md +++ b/docs/resources/control-flow/backend-logic/api/rest-api.md @@ -2,16 +2,26 @@ slug: /resources/backend-logic/rest-api title: API Calls description: Learn the basics of making API calls in your backend logic. -tags: [API, Backend Logic, Control Flow] +tags: + - FlutterFlow + - Resources + - Backend Logic sidebar_position: 1 -keywords: [API, Rest API, Backend Logic, Control Flow, FlutterFlow] +keywords: + - API + - Rest API + - Backend Logic + - Control Flow + - FlutterFlow +last_verified: 2026-09-02 --- - # API Calls -On this page, you will learn the most basic knowledge on various concepts for adding an API call to your project. They are the building blocks of adding an API call. Depending on the API's definition, you may utilize some or all of these concepts to successfully implement the API call in your project. +Use **API Calls** to connect a FlutterFlow app to an HTTP endpoint. Define the method and URL, add any headers, query parameters, variables, or body required by the provider, then test the call and map the response before using it in an action or backend query. + +Always follow the API provider's contract. FlutterFlow configures the request, but it does not determine which method, authentication scheme, content type, parameters, or response shape the endpoint accepts. -Here are they: +This guide covers: * [Headers](#headers) * [Query Parameters](#query-parameters) @@ -46,9 +56,8 @@ To pass the request header: height: 0, width: '100%' }}> - +
@@ -140,7 +147,7 @@ Sometimes you might want to retrieve the values of the response headers. For exa To access the response header: -1. Ensure you have added the [API call action](../api/rest-api.md) and +1. Ensure you have added the [API call action](../api/rest-api.md) and provided the **Action Output Variable Name**. 2. Now, whenever/wherever the **Value Source** is set to **From Variable**, select the **Action Outputs > [Action Output Variable Name]** (e.g., Action Outputs > loginResponse). 3. Set the **API Response Options** to **Get Response Header**. @@ -157,7 +164,7 @@ An example of an URL with query parameters looks like this ([NASA Open API](http Here, `start_date`, `end_date`, and `api_key` are the query parameters passed to receive the specific data. -Here's another example, this API call `` has two query parameters. The `limit` parameter specifies 20 items to load per page, and the `offset` specifies the number of items to skip. This is called offset-based pagination. +For an offset-based pagination endpoint, a URL such as `https://api.example.com/items?limit=20&offset=40` asks for 20 items after skipping the first 40. Parameter names and pagination behavior vary by provider. ### Passing query parameters @@ -172,8 +179,7 @@ To pass the query parameters for `GET` or `DELETE` API call: Below is the example of passing query parameter for the URL -> `https://api.instantwebtools.net/v2/passenger?page=10&size=20` -
+

@@ -184,8 +190,7 @@ In a rare case, you might want to pass the query parameters for the other method from `https://api.instantwebtools.net/v2/passenger?``**page=0**` to `https://api.instantwebtools.net/v2/passenger?``**page=[page]**`). 2. Select the **Variables** tab and [create a new variable](#creating-variables) with the same name you provided inside the brackets. -
+
@@ -212,9 +217,8 @@ Now you can pass values to these variables while triggering the API call from yo height: 0, width: '100%' }}> - +
@@ -271,8 +274,7 @@ To create a request body in text format: 2. Select the **Body** tab and set the Body dropdown to **Text**. 3. Copy-paste your request body and replace the values with the variables by dragging and dropping them inside the request body. -
+
@@ -284,12 +286,11 @@ To create a request body in x-www-form-urlencoded format: 2. Select the **Body** tab and set the Body dropdown to **x-www-form-urlencoded**. 3. Click on the **+ Add Parameter** and enter the **Name** of the parameter. 4. Set the **Value Source** to **Specific Value** or **From Variable**. - 1. If you want to pass this value from your page, app state variable, or from any other source + 1. If you want to pass this value from your page, app state variable, or from any other source (i.e., dynamic value), choose the **From Variable,** and then from the **Select Variable** dropdown, choose the already created variable (see how to [create variable](#creating-variables)) or click on **+ Create New Variable**. Note: This will immediately create a new variable with the same name as of parameter. However, you still need to open the **Variables** tab and set its **Type**. 2. If you want to pass a static/fixed value, select the **Specific Value**, set its **Type,** and enter its **Value**. -
+
@@ -304,16 +305,15 @@ To create a request body in the multipart format: 3. Set the **Value Source** to **From Variable,** and then from the **Select Variable** dropdown, click on **+ Create New Variable**. Note: This will immediately create a new variable with the same name as of parameter. 4. Now move to the **Variables** tab and set the **Type** to **Uploaded File**. This will allow you to pass the file stored locally on the device using an action such as **Upload/Save Media**. -
+
## API response (JSON) to/from Data Type -Converting between API Response (JSON) and Data Types is often referred to as JSON -deserialization and serialization. It allows you to convert JSON data from an API response into -a [**Custom Data Type**](../../../data-representation/custom-data-types.md) when you receive it. Also, +Converting between API Response (JSON) and Data Types is often referred to as JSON +deserialization and serialization. It allows you to convert JSON data from an API response into +a [**Custom Data Type**](../../../data-representation/custom-data-types.md) when you receive it. Also, it enables you to convert your Custom Data Type back into JSON when sending data in an API request. :::info @@ -322,7 +322,7 @@ This is a more robust and maintainable way to work with JSON data in your app. I ### Create Custom Data Type matching to JSON structure -First, [create a Data Type](../../../data-representation/custom-data-types.md#creating-custom-data-type) with the same +First, [create a Data Type](../../../data-representation/custom-data-types.md#creating-custom-data-type) with the same structure as your API response. Here's what the sample JSON response looks like after mapping it into a Custom Data Type. @@ -331,7 +331,7 @@ structure as your API response. Here's what the sample JSON response looks like
Creating custom data type as per the JSON response
-After this, you can choose to [convert to](#json-to-data-type) or [from](#json-from-data-type) +After this, you can choose to [convert to](#json-to-data-type) or [from](#json-from-data-type) the Data Type based on your requirements. ### JSON to Data Type @@ -343,7 +343,7 @@ Let's see how to get the JSON into the Custom Data Type using an example that fe Here's how you do it: 1. First, ensure that you [create a custom data type](#create-custom-data-type-matching-to-json-structure) that matches your JSON structure. -2. Open your API call definition > **Response & Test tab > Response Type >** enable the **Parse as +2. Open your API call definition > **Response & Test tab > Response Type >** enable the **Parse as Data Type**. Select the **Data Type** that you want to convert into. For this example, it's 'AllProducts'. ![img_1.png](../imgs/img_1.png) @@ -357,16 +357,14 @@ Here's how you do it: 3. **Select Field** to the field that holds the list of products, i.e., 'products' for this example. 4. Click **Confirm** twice. -
+

-4. Now, you can bind data in UI elements as you would normally do by setting the **Available +4. Now, you can bind data in UI elements as you would normally do by setting the **Available Options** to **Data Structure Field** and **Select Field** that you want to display. -
+
@@ -386,19 +384,17 @@ Here's how you do it:

-2. In your API call, [create a variable](#creating-variables) with type **JSON** and put it +2. In your API call, [create a variable](#creating-variables) with type **JSON** and put it inside the **Body** section. -
+

-3. On click of **Add** button, we'll store values from UI into the page state variable of custom +3. On click of **Add** button, we'll store values from UI into the page state variable of custom data type. Then, while making an API call, pass that page state variable and set the **Available Options** to **To JSON**. -
+
@@ -558,10 +554,9 @@ This will return the email of all the objects inside the data.

-:::warning[Important] -JSON keys must start with a letter, an underscore, or a dollar sign. They -cannot begin -with a numeric character. However, in cases where you have keys with numeric prefixes, such as `$.0_image`, you can access them using bracket notation, like this: `$.["0_image"]`. +:::warning[Important] +JSON object keys may contain characters that do not work with JSONPath dot notation. For keys +with spaces, punctuation, or numeric prefixes, use bracket notation with a quoted member name—for example, `$['0_image']`. ::: :::info @@ -580,9 +575,8 @@ Under the **Recommended** section, you'll find suggested JSON paths that might c paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding height: 0, width: '100%'}}> - +

:::tip[Watch a video] If you prefer watching a video tutorial, here's the one for you: -
+
::: @@ -791,3 +785,14 @@ Why am I getting a “Current variable is not valid” error? This error typically indicates that the widget isn’t receiving the data type it expects. For example, passing a list of colors directly to a text widget will trigger the error. In such cases, convert or supply the data as a string (or another compatible type) so the widget can properly display it.

+ +## Verify your API call + +Before relying on an API call in your app: + +1. Use **Response & Test** with representative, non-secret values and confirm the HTTP status, response body, and response headers. +2. Test missing, invalid, empty, and expired inputs—not only the success case. +3. Confirm every variable's FlutterFlow type matches the value sent by the app. +4. Validate JSON Paths and **Parse as Data Type** mappings against the provider's current response schema. +5. For private calls, deploy the APIs, verify unauthenticated behavior, and confirm secrets are absent from the generated client. +6. Test from the same platform and mode you will publish. CORS, network policy, OS handlers, and streaming behavior can differ between the builder test, Run/Test Mode, web, and mobile builds. diff --git a/docs/resources/control-flow/backend-logic/api/soap-api.md b/docs/resources/control-flow/backend-logic/api/soap-api.md index a0794493b..68afd72d3 100644 --- a/docs/resources/control-flow/backend-logic/api/soap-api.md +++ b/docs/resources/control-flow/backend-logic/api/soap-api.md @@ -2,20 +2,28 @@ slug: /resources/backend-logic/soap-api title: SOAP APIs description: Learn how to use SOAP APIs in your backend logic with FlutterFlow. -tags: [SOAP APIs, Backend Logic, Control Flow, FlutterFlow] +tags: + - FlutterFlow + - Resources + - Backend Logic sidebar_position: 3 -keywords: [SOAP APIs, Backend Logic, Control Flow, FlutterFlow] +keywords: + - SOAP APIs + - Backend Logic + - Control Flow + - FlutterFlow +last_verified: 2026-09-02 --- import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; # SOAP APIs -SOAP APIs (Simple Object Access Protocol) provide a standardized way to communicate between systems, typically using XML as the message format and operating over protocols such as HTTP, SMTP, and more. +SOAP APIs (Simple Object Access Protocol) provide a standardized XML message format. In FlutterFlow, configure a SOAP operation as an HTTP API call using the endpoint, headers, envelope, and SOAP version required by the service's WSDL or provider documentation. -Unlike REST APIs, which use a flexible request/response model and typically exchange data in JSON, SOAP APIs are built around a formal contract defined by WSDL. This contract ensures strict adherence to communication standards, making SOAP APIs more rigid but also more reliable and secure—ideal for enterprise applications requiring transactional integrity and guaranteed message delivery. +Unlike many REST APIs, which commonly exchange JSON, SOAP services often publish a formal WSDL contract. SOAP does not guarantee security, delivery, or transactional behavior by itself; those properties depend on the service, transport, authentication, and any WS-* extensions it implements. -SOAP APIs are particularly well-suited for scenarios where robust security and detailed error handling are required, such as in financial services or telecommunications. +SOAP remains common in enterprise systems that require contract-driven XML messages and structured SOAP Fault responses. ### Difference between SOAP APIs and REST APIs: @@ -57,7 +65,7 @@ SOAP APIs are particularly well-suited for scenarios where robust security and d ## Building an App -This guide provides a step-by-step instructions on how to add and use SOAP APIs to build an example app that displays a list of countries. Upon tapping on a country name, the user is taken to a details page where the country flag is displayed. By following these instructions, you can learn how to add SOAP APIs into your app and create a basic navigation flow. +This guide provides step-by-step instructions for adding and using SOAP APIs in an example app that displays a list of countries. When the user taps a country, the app navigates to a details page and displays its flag. The final app looks like this: @@ -66,9 +74,8 @@ The final app looks like this: paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding height: 0, width: '100%'}}> - -

\ No newline at end of file +

+ +## Verify the search query + +Test an empty term, exact and partial matches, no-match text, special characters, the result limit, and location filtering when used. Confirm the UI distinguishes loading, empty, and error states and that displayed fields come from the current search result rather than a stale list item. diff --git a/docs/resources/control-flow/backend-logic/backend-query/api-call-query.md b/docs/resources/control-flow/backend-logic/backend-query/api-call-query.md index be14b61bc..917d2292e 100644 --- a/docs/resources/control-flow/backend-logic/backend-query/api-call-query.md +++ b/docs/resources/control-flow/backend-logic/backend-query/api-call-query.md @@ -2,14 +2,25 @@ slug: /resources/backend-query/api-call-query title: API Call Query description: Learn how to perform an API call query in your FlutterFlow app. -tags: [API Call, Backend Logic, Control Flow, FlutterFlow, Backend Query] +tags: + - FlutterFlow + - Resources + - Backend Query sidebar_position: 4 -keywords: [API Call, Backend Logic, Control Flow, FlutterFlow, Backend Query] +keywords: + - API Call + - Backend Logic + - Control Flow + - FlutterFlow + - Backend Query + - use an API call as a backend query +ai_queries: + - use an API call as a backend query +last_verified: 2026-09-02 --- - # API Call Query -You can use the **API Call Query** to trigger an API call automatically as soon as the page or widget is loaded. This is helpful if you want to retrieve the data from an API call and display it on a page or widget. For example, showing a list of items in a ListView, showing users details on several Text widgets. +Use an **API Call** backend query to run a configured API call when a page or widget loads and expose its response to descendants. Common uses include generating ListView children from an array or displaying profile fields in Text widgets.

@@ -19,9 +30,8 @@ You can use the **API Call Query** to trigger an API call automatically as soon height: 0, width: '100%' }}> - +
@@ -80,11 +92,12 @@ Once you have the API Call query defined, you can use the data retrieved from th 3. Select the **Source** as the **YOUR_API_CALL_NAME Response**. 4. Set the **API response Options** to **JSON Body**. 5. Set the **Available Options** to **JSON Path**. -6. Set the **JSON Path Name** to either the custom JSON path or use the already created JSON +6. Set the **JSON Path Name** to either the custom JSON path or use the already created JSON path. See how to [**create a JSON path**](../../backend-logic/api/rest-api.md#add-json-predefined-path). 7. Click **Confirm**. -
+
+## Verify the API query +Use **Test API Call** to confirm the response shape first. Then test the page with successful, empty, malformed, non-2xx, slow, and paginated responses. Verify every JSON path and data type, provide loading and error UI, and confirm input-variable changes do not create unintended duplicate requests. diff --git a/docs/resources/control-flow/backend-logic/backend-query/backend-query.md b/docs/resources/control-flow/backend-logic/backend-query/backend-query.md index ef8f532c6..6bfa50e03 100644 --- a/docs/resources/control-flow/backend-logic/backend-query/backend-query.md +++ b/docs/resources/control-flow/backend-logic/backend-query/backend-query.md @@ -1,10 +1,19 @@ --- slug: /resources/backend-query title: Backend Query -description: Learn about backend queries in your FlutterFlow app, including how to set up and manage queries. -tags: [Backend Query, Backend Logic, Control Flow, FlutterFlow] +description: >- + Learn about backend queries in your FlutterFlow app, including how to set up + and manage queries. +tags: + - FlutterFlow + - Resources + - Backend Query sidebar_position: 1 -keywords: [Backend Query, Backend Logic, Control Flow, FlutterFlow] +keywords: + - Backend Query + - Backend Logic + - Control Flow + - FlutterFlow --- import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; @@ -19,7 +28,7 @@ We offer you the following types of Backend Queries that you can specify on any * [**Query Collection or Table**](query-collection.md)**:** This query type is used to fetch a single record or a list of records from a Firestore Collection or Supabase Table. * [**Document from Reference**](document-from-reference.md)**:** Used to retrieve the details from a document reference. -* [**API Call Query**](api-call-query.md)**:** Used to initiate an API +* [**API Call Query**](api-call-query.md)**:** Used to initiate an API call. * [**SQLite Query**](sqlite-query.md): Used to execute the SQL statements. * [**Algolia Search**](algolia-search-query.md)**:** Used to trigger an Algolia search on a Firestore Collection. @@ -39,9 +48,9 @@ We offer you the following types of Backend Queries that you can specify on any ## Change loading indicator -While the backend query is busy retrieving results, it shows the default *Project Theme Loading -Indicator* (which you can change from -[**Navigation menu**](../../../../../docs/intro/ff-ui/builder.md#navigation-menu) *> Theme +While the backend query is busy retrieving results, it shows the default *Project Theme Loading +Indicator* (which you can change from +[**Navigation menu**](../../../../../docs/intro/ff-ui/builder.md#navigation-menu) *> Theme Settings > Design System > Loading Indicator*.) However, if you want to replace this with a custom loading indicator in a specific backend query, follow the instructions below:
Design System > Loading Indicator*.) However, if you want to replace height: 0, width: '100%' }}> -
+
@@ -93,14 +100,13 @@ Sometimes, you might want to display the same list of items with a little modifi To copy-paste the query: -1. Select the widget (e.g., ListView, GridView, etc.) where you have already added the backend +1. Select the widget (e.g., ListView, GridView, etc.) where you have already added the backend query. 2. Select the **Backend Query** tab, and click the **Copy** button. 3. Now, select the widget (where you want to add the query), move to the **Backend Query** tab, and click **Paste Backend Query** button. 4. Click **Confirm**. -
+
@@ -110,8 +116,7 @@ You might want to utilize the same backend query on multiple widgets on a page. To move the query up to any parent widget, simply select the up arrow button and select the parent widget you would like the query to move to. -
+
@@ -127,8 +132,7 @@ To display the empty list widget: 4. Try toggling the **View in UI Builder**. This allows you to see your empty list widget on canvas (before you actually run the app). 5. You can also control the size and centering of the widget using the available options. -
+
@@ -173,8 +177,7 @@ To improve performance, you can cache the data on the details page so that it ca Here is how it looks: -
+

@@ -184,7 +187,7 @@ In the visual above, see how the loading indicator appears for the first time a To cache the backend query: -1. Ensure you have added a backend query. For this example, to retrieve data from a Firebase +1. Ensure you have added a backend query. For this example, to retrieve data from a Firebase document, we add a backend query at the page level as *Single Time Query*. We use a document reference to get the employee details.
@@ -196,31 +199,28 @@ document, we add a backend query at the page level as *Single Time Query*. We us 3. Determine the **Scope** of the cache. If you set it to **App Level** and the *exact* same query is made on any other page of the app, it will display the result from the cache. However, if you set the **Page Level**, the cached result will be used only on that page if the query is made multiple times on the same page. 4. If the current query is completely new/different, create a **Query Name**. If not, and you want to use the cached result of this query (that might be created somewhere else), select the name from the list. -
+

-5. If we leave this example here, we'll have data inaccuracy issues. That means when any employee +5. If we leave this example here, we'll have data inaccuracy issues. That means when any employee data is cached, the same data will be used for all employees, which is not what we want. We want to cache data for all individual employees. To do so, we can set the **Unique Key**. Here the unique key can be the employee id or the document reference. -
+
-
+

-6. At this point, we have enabled the caching, but we still have one problem. Once the query is +6. At this point, we have enabled the caching, but we still have one problem. Once the query is cached, it will be used forever, although we update the data in our backend. This is because we are not clearing or invalidating the cache at the appropriate time. To properly invalidate the cache, you can use the **Should Override Cache** property OR **Clear Query Cache** action. This helps you remove the cached data that has become stale or outdated. - 1. The *Should Override Cache* property accepts a boolean (True/False). That means we can + 1. The *Should Override Cache* property accepts a boolean (True/False). That means we can provide a variable (e.g., an *App State* variable named *isCacheOverride)* that knows when to override the cache. So create one and set it here. 2. Create one more *App State* variable, something like *lastCacheTime,* and set the current time as default. This will be used to save the time of results retrieved from the backend. You'll better understand how helpful it is in the logic we add in the next step. @@ -231,19 +231,18 @@ cached, it will be used forever, although we update the data in our backend. Thi

-7. Now, we must add a logic that determines whether to override the cache (every time when the +7. Now, we must add a logic that determines whether to override the cache (every time when the page is loaded) and set the *isCacheOverride* variable accordingly. Here is how it goes: 1. First, check if the *lastCacheTime* is set or not. If not, set the current time to it. 2. Then the idea is to create one custom action that checks if the current time is more than 30 minutes ahead of the *lastCacheTime*. **Note** that 30 minutes is the cache expiration time, and here, it is kept minimum just for simplification purposes; It's important to carefully choose the appropriate expiration time for your cache based on the nature of your data. 3. if **True** : - 1. [Update](../../../../resources/data-representation/app-state.md#update-app-state-action) the **lastCacheTime** with + 1. [Update](../../../../resources/data-representation/app-state.md#update-app-state-action) the **lastCacheTime** with the current time and **isCacheOverride** to True. Make sure you keep the **Update Type** to **Rebuild Current Page** so that the backend query is made again, which will invalidate the cache and display updated data. 2. You can also add an action to [Clear Query Cache](#). 3. Continuing the same action flow, [wait](../../../../resources/control-flow/time-based-logic/wait-action.md) for 1 sec and again update **isCacheOverride** to **False** so that the cached result won't override on page load for the next 30 min. -
+

@@ -267,7 +266,7 @@ bool isOverrideCacheAction(DateTime cacheTime) {
:::tip -You can have a separate *lastCacheTime* variable for all the employee records to avoid any +You can have a separate *lastCacheTime* variable for all the employee records to avoid any conflict with others. Failing to do so may keep on updating the common *lastCacheTime* variable, and you might not see updated data. For example, creating a list of JSON that contains the id and *lastCacheTime* of an employee might help. Like this: `{ "id": 1, "lastCacheTime": '2023-03-22T14:30:00+00:00', }` @@ -295,9 +294,8 @@ Follow the steps below to add this action to any widget. paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding height: 0, width: '100%'}}> - - \ No newline at end of file + + +## Verify the document query + +Test a valid reference, a null reference, a reference to the wrong collection, a missing document, and a permission-denied read. Confirm live updates occur only when **Single Time Query** is disabled and that loading, empty, and error states do not display stale field values. diff --git a/docs/resources/control-flow/backend-logic/backend-query/query-collection.md b/docs/resources/control-flow/backend-logic/backend-query/query-collection.md index 37db013e5..671e1dcd5 100644 --- a/docs/resources/control-flow/backend-logic/backend-query/query-collection.md +++ b/docs/resources/control-flow/backend-logic/backend-query/query-collection.md @@ -2,16 +2,25 @@ slug: /resources/backend-query/query-collection title: Query Collection / Table description: Learn how to query a collection in your FlutterFlow app. -tags: [Query Collection, Backend Query, Backend Logic, Control Flow, FlutterFlow] +tags: + - FlutterFlow + - Resources + - Backend Query sidebar_position: 2 -keywords: [Query Collection, Backend Query, Backend Logic, Control Flow, FlutterFlow] +keywords: + - Query Collection + - Backend Query + - Backend Logic + - Control Flow + - FlutterFlow +last_verified: 2026-09-02 --- import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; # Query Collection / Table -Quering Firestore Collection or Supabase Table helps you to retrieve a record (or a list of records) automatically whenever a +Querying a Firestore collection or Supabase table retrieves a record, list of records, or supported aggregate automatically when a user navigates to the page containing the query. The information that is present in the record can be used to update any widget present inside. @@ -30,9 +39,8 @@ backend query: the [Properties Panel](../../../../intro/ff-ui/builder.md#properties-panel) (the right menu). 3. Select the **Query Type** as ***Query Collection***. 4. Choose the Firestore **Collection** to use for performing the query. -5. Under **Query Type**, select either ***List of Documents*** (returns a list of document - references) or ***Single Document*** (returns only one document reference). -6. If you have selected the **List of Documents**in the previous step, you can set a **Limit** to +5. Under **Query Type**, select ***List of Documents***, ***Single Document***, or ***Count***. +6. If you selected **List of Documents**, you can set a **Limit** to the maximum number of documents returned. 7. If you want to apply any **filter** for retrieving the documents, click **+ Filter** button. Select a **Field Name** that you want to use as the filter, choose a **Relation** ( @@ -45,7 +53,7 @@ backend query: - **Single Time Query**: When this is disabled, the query results will automatically refresh whenever documents or rows are created, updated, or deleted. However, for **Supabase**, this option is enabled by default, meaning the query will run only once. To enable real-time updates, you must turn it off. - **Ignore Empty Filter Values**: Disabled by default, meaning the query will attempt to find documents with empty text fields if any filter value is empty. When enabled, the query will ignore fields with empty filter values instead. - **Filter on Null Values**: By default, if any filter value is null, the query will ignore that filter. Enabling this option will include null filters in the query. - - **Enable Infinite Scroll**: To implement infinite scrolling, enable this option and follow the instructions here. + - **Enable Infinite Scroll**: Load records in pages as the user scrolls. Set a page size and use a deterministic order; include the complete primary key as the final ordering for Supabase pagination so tied values cannot skip or duplicate rows. 10. Click **Confirm**. 11. If the selected query returns a list of documents and if it's applied to any flexible widget (like `Column`, `Row`, or `ListView`) then FlutterFlow will generate the children widgets dynamically. A dialog will be displayed with a similar message, click **Confirm**. @@ -60,9 +68,8 @@ The instructions to query a Supabase table are almost the same, except that for height: 0, width: '100%' }}> - +
@@ -45,12 +53,11 @@ com/embed/29001cdee28d4d058dd711b3bbb70b7e?sid=d5be04cc-1ce3-4f16-98e1-5b929c0f6 Once you have the SQLite query defined, you can use the data retrieved from the query to display on widgets present inside. Follow the steps below: 1. Select the **widget** (e.g., `Text`) on which you want to display the data. -2. From the Properties Panel, open the **Set from Variable** menu **>** select **[your query name] Row** **>** select the column data that you want display here. +2. From the Properties Panel, open **Set from Variable**, select **[your query name] Row**, and select the column value to display. 3. Click **Confirm**. -
- - +
+## Verify the SQLite query +Test a fresh local database, no matching rows, one row, multiple rows, null columns, and a failed query. Confirm query parameters have compatible types, list results generate the expected children, single-row UI handles no result, and a write action refreshes or rebuilds the read query when the screen must show the new data. diff --git a/docs/resources/control-flow/concepts.md b/docs/resources/control-flow/concepts.md index 1bb3f34ab..206757c42 100644 --- a/docs/resources/control-flow/concepts.md +++ b/docs/resources/control-flow/concepts.md @@ -1,13 +1,21 @@ --- slug: /resources/control-flow-concepts title: Control Flow Concepts -description: Understand and implement control flow in your FlutterFlow app to manage the execution of statements, instructions, and function calls under various conditions. -tags: [Control Flow, FlutterFlow, Concepts] +description: >- + Understand and implement control flow in your FlutterFlow app to manage the + execution of statements, instructions, and function calls under various + conditions. +tags: + - FlutterFlow + - Resources + - Control Flow Concepts sidebar_position: 2 -keywords: [Control Flow, FlutterFlow, Concepts] +keywords: + - Control Flow + - FlutterFlow + - Concepts +last_verified: 2026-09-02 --- - - # Control Flow Concepts In app development, control flow refers to the order in which individual statements, @@ -31,8 +39,6 @@ The primary conditional statements are `if`, `if-else`, and `else`. - **`if` Statement:** The if statement evaluates a condition and executes a block of code if the condition is true. -The if statement evaluates a condition and executes a block of code if the condition is true. - ![if-condition.png](functions/img/if-condition.png) @@ -56,7 +62,7 @@ This example demonstrates multiple conditions. If `userIsLoggedIn` is true, it s ### Implementing Conditionals -In FlutterFlow, you can implement conditional logic in two primary ways: +In FlutterFlow, you can implement conditional logic in two primary ways: - **[When Setting Properties](functions/conditional-logic.md#setting-widget-properties-with-conditional-logic)** @@ -64,31 +70,33 @@ In FlutterFlow, you can implement conditional logic in two primary ways: - **[Conditional Actions](functions/conditional-logic.md#conditional-actions)** - You can also perform conditional actions in FlutterFlow, where certain actions are executed - only if specified conditions are met. This is useful for implementing logic like + You can also perform conditional actions in FlutterFlow, where certain actions are executed + only if specified conditions are met. This is useful for implementing logic like navigating to different pages based on user input or showing/hiding widgets. Example: If the user clicks a button and a form is valid, navigate to the next screen; otherwise, show an error message. -:::info -Check out the [**complete guide**](functions/conditional-logic.md) here. Are you looking to learn about implementing conditional UI instead? Check out our **[Responsiveness 101](../../ff-concepts/layout/responsive-layout.md)** guide instead. +:::info +Check out the [**complete guide**](functions/conditional-logic.md) here. Are you looking to learn about implementing conditional UI instead? Check out our **[Responsiveness 101](../../ff-concepts/layout/responsive-layout.md)** guide instead. ::: ## Sequential vs Parallel Logic Flow - **Sequential Logic Flow**: - Actions are executed **one after the other**. Each action waits for the -previous one to complete before starting. This is useful for tasks that depend on the outcome of previous actions. + Actions are executed **one after the other**. Each action waits for the +previous one to complete before starting. This is useful for tasks that depend on the outcome of previous actions. **Example:** Submitting a form, waiting for a server response, and then showing a confirmation message. -- **Parallel Logic Flow** - Multiple actions are executed at the **same time**, independently of each +- **Parallel Logic Flow**: + Multiple actions are executed at the **same time**, independently of each other. This is useful for tasks that can be done simultaneously and do not depend on each other's outcomes. - + **Example:** Loading data from multiple sources simultaneously to speed up the data fetching process. + ![parallel-sequential.png](functions/img/parallel-sequential.png) + ## Asynchronous Functions Asynchronous functions are operations that do not complete immediately and may finish at a @@ -106,38 +114,28 @@ They can be made **blocking** or **non-blocking** depending on the use case. Som Blocking actions are actions that halt the execution of subsequent actions until they are completed. These actions typically involve operations that take time, such as network requests or animations. :::tip[Generated Code] -In the **generated code**, FlutterFlow uses the `await` keyword to pause the execution of an -asynchronous function until the operation completes before proceeding to the next +In the **generated code**, FlutterFlow uses the `await` keyword to pause the execution of an +asynchronous function until the operation completes before proceeding to the next function. This approach is commonly used to handle asynchronous functions, ensuring that each operation finishes before the subsequent one begins. -In the following example from **generated code**, the code **awaits** on `actions.getRandomIntAfterWait()` because it is an asynchronous function that takes around 2 seconds to complete and provide a result (in this case, a random integer). -```dart +In the following simplified example, the generated code waits for an asynchronous action before using its result: +```jsx _model.result = await actions.getRandomIntAfterWait(); _model.text1Value = _model.result.toString(); ``` -The result of the `actions.getRandomIntAfterWait()` is stored in `model.result` variable and -then the result then set to a Text widget using the Page State variable `text1Value`. +The result of `actions.getRandomIntAfterWait()` is stored before the page state value is updated. ::: ### Non-Blocking Actions -Non-blocking actions, on the other hand, allow the program to continue executing other -subsequent tasks while waiting for the initial actions to complete in the background. +Non-blocking actions, on the other hand, allow the program to continue executing other +subsequent tasks while waiting for the initial actions to complete in the background. :::tip[Generated Code] -In the **generated code**, when an asynchronous function is made **non-blocking**, FlutterFlow removes the `await` keyword. This means the subsequent function will not wait for the asynchronous action to complete and will move to the next action immediately. +In generated code, FlutterFlow starts a **Non-Blocking** action without awaiting its completion. The next action in the main flow can therefore run immediately. Outputs and completion-dependent side effects from the non-blocking action are not safe inputs for that next action. -The previous example will no longer work because it doesn't await the asynchronous function -`actions.getRandomIntAfterWait()`. As a result, the variable `model.result` may not be -ready or available when `_model.text1Value = _model.result.toString();` is executed. - -``` -_model.result = actions.getRandomIntAfterWait(); -_model.text1Value = _model.result.toString(); // will throw errors -``` - -To ensure proper execution, make only those actions non-blocking whose subsequent actions do not depend on the results from these initial functions. +Use **Non-Blocking** only when later actions do not depend on its result. Also handle failures within the detached work where possible; the main flow has already continued. ::: @@ -149,6 +147,11 @@ To ensure proper execution, make only those actions non-blocking whose subsequen | Allows the subsequent action to run **immediately** after the current one without waiting for the current action to complete. | Allows users to run two or more actions at the **same time** independently. | | **Only asynchronous** functions can be made non-blocking. | **Both asynchronous and synchronous** functions can be included in parallel actions. | | Ideal for tasks where the result of the action is not immediately needed by the next action. | Ideal for independent tasks that can be executed simultaneously to improve efficiency. | -| Ensures the app remains responsive by not waiting for long-running tasks. | Helps in reducing overall execution time by performing multiple tasks concurrently. | -| **Example**: Fetching data in the background while allowing user interaction. | **Example**: Loading data from two APIs simultaneously to save time. | +| Lets the configured flow continue without waiting; it does not move work to an operating-system background service. | Helps reduce overall execution time by performing multiple branches concurrently. | +| **Example**: Starting independent analytics logging without delaying navigation. | **Example**: Loading data from two APIs simultaneously to save time. | + +Parallel branches run concurrently, and the action flow waits for all of them before continuing after the parallel block. Keep dependent steps in sequence rather than placing them in separate branches. + +## Verify execution order +Add temporary UI updates before and after each action, then run the flow in **Test Mode** with fast, slow, successful, and failed responses. Confirm sequential dependencies retain their order, parallel branches do not depend on one another, and non-blocking work is not expected to provide an output to the next action. diff --git a/docs/resources/control-flow/functions/action-blocks.md b/docs/resources/control-flow/functions/action-blocks.md index 2ccfe7a46..f317a1d41 100644 --- a/docs/resources/control-flow/functions/action-blocks.md +++ b/docs/resources/control-flow/functions/action-blocks.md @@ -1,35 +1,46 @@ --- slug: /resources/functions/action-blocks title: Action Blocks -description: Learn how to use Action Blocks in your FlutterFlow app to and create reusable actions. -tags: [Action Blocks, Backend Query, Backend Logic, Control Flow] +description: >- + Learn how to use Action Blocks in your FlutterFlow app to create reusable + actions. +tags: + - FlutterFlow + - Resources + - Functions sidebar_position: 3 -keywords: [Action Blocks, Backend Query, Backend Logic, Control Flow, FlutterFlow] +keywords: + - Action Blocks + - Backend Query + - Backend Logic + - Control Flow + - FlutterFlow +last_verified: 2026-09-02 --- +# Action Blocks An Action Block is a set of actions that perform a specific task and can be reused in different parts of the app. If you find yourself repeatedly performing a particular set of operations in your app, it may be helpful to create an Action Block. This allows you to break down complex actions into smaller, more manageable units, making them easier to understand and modify in the future. Action Blocks have different scopes, which determine their availability: | **Action Block Type** | **Description** | **Scope** | |----------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------| -| **App Level Action Blocks** | Usable across the entire app. You can create an App Level Action Block from any page or component, and it will be accessible for viewing or editing from any page or component as well. | Internally, an App Level Action Block can only access the state variables available in its scope (e.g., app state variables). | -| **Page Level Action Blocks** | Restricted to the page in which they were created. These can access the state variables available in their scope, such as page state variables, as well as variables above their scope, such as [App State variables](../../../resources/data-representation/app-state.md). | Page Level Action Blocks can access page state variables and App State variables. | -| **Component Level Action Blocks**| Restricted to the component in which they were created. These can access the state variables available in their scope, such as component state variables, as well as variables from higher scopes, like page and App State variables. | Component Level Action Blocks can access component state variables, page state variables, and App State variables. | +| **App Level Action Blocks** | Usable across the entire app. Create one from a page or component, then select **App Level** to view or edit it from other pages and components. | App-scoped values, including [App State](../../../resources/data-representation/app-state.md), plus explicit Action Parameters. | +| **Page Level Action Blocks** | Restricted to the page where they were created. | That page's state and other page-scoped values, App State, plus explicit Action Parameters. | +| **Component Level Action Blocks**| Restricted to the component where they were created. | That component's state and parameters, App State, plus explicit Action Parameters. Pass caller-page values into the block instead of assuming it can read arbitrary Page State. | :::note[Unsupported Actions in Action Blocks] -Some actions are not supported and cannot be used in an Action Block. By default, these actions are hidden in the Action Block Editor. -For example, actions under the **Firebase Authentication** category, **Start Periodic Action**, **Upload Data**, and others. +Some actions are not supported in Action Blocks. The editor hides unavailable actions for the selected scope. Availability can change as capabilities are added, so use the action picker as the current source of truth. ::: ## Action Blocks Structure -When creating an Action Block, the process of defining the flow is similar to **[defining -Actions](action-flow-editor.md#adding-an-action-example)**. -The main difference is in choosing the scope and defining the input & output values of the +When creating an Action Block, the process of defining the flow is similar to **[defining +Actions](action-flow-editor.md#adding-an-action-example)**. +The main difference is in choosing the scope and defining the input & output values of the Action Block. ### Choosing the Scope of Action Block -As discussed, Action Blocks can be **App Level, Page Level**, or **Component Level**. App Level Action Blocks can be created from any widget's action properties throughout the app. However, Page Level or Component Level Action Blocks are only available in the Page or Component where they were created. +As discussed, Action Blocks can be **App Level, Page Level**, or **Component Level**. App Level Action Blocks can be created from any widget's action properties throughout the app. However, Page Level or Component Level Action Blocks are only available in the Page or Component where they were created. Usually, you will see a dropdown to choose between App Level, Page Level, or Component Level. Choose the scope based on your Action Block's use case. @@ -38,8 +49,8 @@ Usually, you will see a dropdown to choose between App Level, Page Level, or Com ### Action Parameters -Action Blocks have access to the state variables available in the same scope as the Action Block -(for e.g., Page State variables can be accessed from Page Level Action Blocks). However, there +Action Blocks have access to the state variables available in the same scope as the Action Block +(for e.g., Page State variables can be accessed from Page Level Action Blocks). However, there will be times when you may need to input some parameters for the Action Block to perform its logic. These are called **Action Parameters**, and they can be added from the Action Flow Editor when you create a new Action. For example, here is a small demo where we create an Action Block with an input parameter. @@ -48,13 +59,12 @@ In this example, we add an item to the wishlist of an e-commerce app. Let's say
-
+Use **Add Return Value** to terminate the block with a value that matches its declared return type. A caller can use that output only after the Action Block completes; keep the call blocking when a later action depends on the result. +## Verify an Action Block +Run the block from at least two intended callers with normal, empty, null, and error inputs. Confirm required parameters are supplied, the block reads only values available in its declared scope, every return path produces a compatible value, and caller actions that use the output wait for completion. diff --git a/docs/resources/control-flow/functions/action-flow-editor.md b/docs/resources/control-flow/functions/action-flow-editor.md index fe0339ebc..7ee6ceaf6 100644 --- a/docs/resources/control-flow/functions/action-flow-editor.md +++ b/docs/resources/control-flow/functions/action-flow-editor.md @@ -1,13 +1,24 @@ --- slug: /resources/functions/action-flow-editor title: Actions -description: Learn how to use the Action Flow Editor in your FlutterFlow app to manage and streamline your backend logic. -tags: [Action Flow Editor, Backend Query, Backend Logic, Control Flow, Actions] +description: >- + Learn how to use the Action Flow Editor in your FlutterFlow app to manage and + streamline your backend logic. +tags: + - FlutterFlow + - Resources + - Functions toc_max_heading_level: 5 sidebar_position: 2 -keywords: [Action Flow Editor, Actions, Backend Query, Backend Logic, Control Flow, FlutterFlow] +keywords: + - Action Flow Editor + - Actions + - Backend Query + - Backend Logic + - Control Flow + - FlutterFlow +last_verified: 2026-09-02 --- - # Actions Effectively managing user interactions is essential for developing interactive applications. @@ -19,9 +30,9 @@ Designing interactivity involves two steps: **Action Triggers** represent a specific event, while **Actions** are functions executed in response to the triggered event. Common triggers are: -- **On Tap**: Triggered on tapping on a widget or specifically buttons. -- **On Selected:** Triggered on selecting an option from a dropdown list. -- **On Page Load:** Triggered on loading a page +- **On Tap:** Triggered when a user taps a supported widget. +- **On Selected:** Triggered when a value changes in a supported selection widget. +- **On Page Load:** Triggered when a page loads. Actions are tasks or operations that are performed in response to an event detected by a trigger. @@ -45,9 +56,8 @@ To learn more about **Action Triggers** and its types, refer [**here**](action-t paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding height: 0, width: '100%'}}> - +

:::warning[Exposed by FlutterFlow] @@ -81,7 +92,7 @@ specific to the selected trigger. height: 0, width: '100%' }}> - - \ No newline at end of file + + +## Verify an action flow + +Run each trigger in **Test Mode** with success, empty, cancel, and error inputs. Confirm actions execute in the intended order, conditional branches are mutually correct, loops terminate, parallel branches are independent, and non-blocking actions do not supply values to immediate follow-up actions. Review the action-flow issue indicator before publishing. diff --git a/docs/resources/control-flow/functions/action-triggers.md b/docs/resources/control-flow/functions/action-triggers.md index 96d8f8e01..74b880f23 100644 --- a/docs/resources/control-flow/functions/action-triggers.md +++ b/docs/resources/control-flow/functions/action-triggers.md @@ -2,12 +2,20 @@ slug: /resources/functions/action-triggers title: Action Triggers description: Explore the action triggers available in FlutterFlow. -tags: [Action Flow Editor, Backend Query, Backend Logic, Control Flow, Actions] +tags: + - FlutterFlow + - Resources + - Functions toc_max_heading_level: 5 sidebar_position: 2 -keywords: [Action Flow Editor, Actions, Backend Query, Backend Logic, Control Flow, FlutterFlow] +keywords: + - Action Flow Editor + - Actions + - Backend Query + - Backend Logic + - Control Flow + - FlutterFlow --- - # Action Triggers **Action Triggers** represent specific events that occur when a user interacts with the app, such as tapping a button, selecting an option from a dropdown, or loading a new page. When an Action Trigger is invoked by one of these interactions, it initiates a corresponding **Action**—a task or operation that responds to the event. @@ -17,7 +25,7 @@ In essence, Action Triggers are the '_listeners_' in your app, keeping an eye ou ## Types of Action Triggers ### Page & Component Root Level Triggers -FlutterFlow provides several action triggers that allow you to respond to a page or component being initialized, or things like a key press event. +FlutterFlow provides several action triggers that allow you to respond to a page or component being initialized, or things like a key press event. For more information on these triggers, see the [Page Actions & Lifecycle](/resources/ui/pages/page-lifecycle) and [Components Actions & Lifecycle](/resources/ui/components/component-lifecycle) pages. @@ -36,9 +44,8 @@ Here’s an example of showing a message on button click using the **On Tap** tr paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding height: 0, width: '100%'}}> - - \ No newline at end of file + + +## Related documentation + +See [Action Blocks](/resources/functions/action-blocks) for a related FlutterFlow workflow. + +## Verify conditional logic + +Create test cases for every branch, including null, empty, boundary, and unexpected values. In **Test Mode**, confirm only the intended action branch runs and each conditional property resolves to the expected type. Pay particular attention to the first matching condition when rules overlap. diff --git a/docs/resources/control-flow/functions/loops.md b/docs/resources/control-flow/functions/loops.md index e39011b01..0df8990ff 100644 --- a/docs/resources/control-flow/functions/loops.md +++ b/docs/resources/control-flow/functions/loops.md @@ -1,12 +1,22 @@ --- slug: /resources/functions/loops title: Loops -description: Learn how to implement loops in your FlutterFlow app to iterate over data and perform repeated actions. -tags: [Loops, Backend Query, Backend Logic, Control Flow, FlutterFlow] +description: >- + Learn how to implement loops in your FlutterFlow app to iterate over data and + perform repeated actions. +tags: + - FlutterFlow + - Resources + - Functions sidebar_position: 5 -keywords: [Loops, Backend Query, Backend Logic, Control Flow, FlutterFlow] +keywords: + - Loops + - Backend Query + - Backend Logic + - Control Flow + - FlutterFlow +last_verified: 2026-09-02 --- - # Loops **Loops** in FlutterFlow allow you to perform repetitive tasks without writing complex code. This is useful when working with lists of data or when you want to repeat actions a certain number of times. @@ -15,9 +25,9 @@ There are two types of loops supported in FlutterFlow: ## While Condition Loops -A **While Condition** loop requires a condition. The actions within the loop will continue to trigger as long as the condition holds true. When the condition becomes false, the loop terminates, and the next actions in the workflow will trigger. +A **While Condition** loop requires a condition. The actions within the loop will continue to trigger as long as the condition holds true. When the condition becomes false, the loop terminates, and the next actions in the workflow will trigger. -For example, you can use a While Condition loop to continuously check if a user is still within a geofenced area. As long as the condition `isUserInLocation == true` holds, the app might keep checking for updates or show a live indicator. +For example, use a While Condition loop for a bounded retry flow: attempt an operation, increment an attempt counter, optionally add **Wait (Delay)**, and continue only while the operation has not succeeded and the maximum attempt count has not been reached. ![loop-block.png](img/loop-block.png) @@ -30,14 +40,16 @@ For example, if you have a list of items in a shopping cart and want to calculat You can also customize how the loop iterates: - **Start Index**: Where the loop starts (default is `0`). -- **End Index**: Where the loop ends (default is the length of the list). -- **Step Size**: Interval between each iteration (e.g., set to `2` to loop through every second item). +- **End Index**: The last index to include. Leave it empty to continue through the end of the list. +- **Step Size**: Positive interval between iterations; the default is `1`. Set it to `2` to process every second item. - **Reverse Order**: Enables the loop to iterate from the end of the list to the beginning (e.g., showing the latest messages first). ![loop-over-list.avif](img/loop-over-list.avif) Inside a loop, you can access the current item and its index. This gives you the ability to work with each item individually, such as displaying item-specific data and making calculations. +The loop processes its body sequentially. If the body contains an asynchronous action, the next iteration waits unless that action is explicitly non-blocking. Do not make an action non-blocking when a later step or iteration depends on its result. + ![access-item-inside-loop.avif](img/access-item-inside-loop.avif) :::tip[Nested Loops] @@ -47,17 +59,17 @@ You can also add a loop inside another loop to handle related data structures. F ::: -## Loop Breaks +## Loop Breaks :::danger[AVOID an INFINITE LOOP] -Be careful with loop actions, as they can cause your app to enter an infinite loop if the condition never becomes false. Always ensure that the condition will be met at some point so the loop can exit. +Be careful with loop actions, as they can cause your app to enter an infinite loop if the condition never becomes false. Update a value used by the condition, enforce a maximum attempt or elapsed-time bound, and add a delay when repeatedly polling an external condition. ::: If the intended operation is completed before the condition becomes false, you must add a **Loop Break** action in your workflow to exit the loop. -**Loop Breaks** are statements used to exit a loop prematurely, before the loop's normal termination +**Loop Breaks** are statements used to exit a loop prematurely, before the loop's normal termination condition is met. They are typically used to stop the loop when a certain condition is satisfied, -preventing unnecessary iterations and allowing the program to proceed to the next section of +preventing unnecessary iterations and allowing the program to proceed to the next section of actions. **Key Points:** @@ -66,4 +78,12 @@ actions. - **Implementation:** Typically implemented with the "Add Break" node in Action Flow Editor. - **Usage:** Commonly used to avoid infinite loops or to stop looping once a desired result is achieved. -![loop-block-return.png](img/loop-block-return.png) \ No newline at end of file +![loop-block-return.png](img/loop-block-return.png) + +## Related documentation + +See [Action Blocks](/resources/functions/action-blocks) for a related FlutterFlow workflow. + +## Verify a loop + +Test an empty list, a one-item list, the chosen start and inclusive end indices, step sizes, reverse order, and the break condition. For a While Condition loop, force both success and maximum-attempt exits. Confirm each item is processed once in the intended order and that failures cannot leave the UI in an endless loop. diff --git a/docs/resources/control-flow/functions/utility-actions.md b/docs/resources/control-flow/functions/utility-actions.md index c930ca1e7..25f7ac8c0 100644 --- a/docs/resources/control-flow/functions/utility-actions.md +++ b/docs/resources/control-flow/functions/utility-actions.md @@ -1,10 +1,22 @@ --- slug: /resources/functions/utility-actions title: Utility Actions -description: Learn about the built-in utility Actions available in FlutterFlow to enhance your app's UI logic. -tags: [Functions] +description: >- + Learn about the built-in utility Actions available in FlutterFlow to enhance + your app's UI logic. +tags: + - FlutterFlow + - Resources + - Functions sidebar_position: 6 -keywords: [Built-in Functions, Backend Query, Backend Logic, Control Flow, FlutterFlow, pub.dev] +keywords: + - Built-in Functions + - Backend Query + - Backend Logic + - Control Flow + - FlutterFlow + - pub.dev +last_verified: 2026-09-02 --- import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; @@ -25,9 +37,8 @@ When this action is triggered, it opens the color picker, where users can custom paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding height: 0, width: '100%'}}> - -

\ No newline at end of file +

+ +## Verify utility actions + +Test utility actions on every target platform before release: + +- Confirm picker cancellation as well as selection, and handle a null or unchanged picker state when the user dismisses the dialog. +- For **Biometric Verification**, test a successful match, a failed match, a device with no enrolled biometric, and the **Allow Biometric Only** setting. Branch on the action output rather than assuming authentication succeeded. +- **Copy to Clipboard** is not supported in Test Mode; use Run Mode or a built app. +- **Send Email**, **Call Number**, and **Send SMS** open an external OS application. A simulator, browser, or device without a configured handler may not complete the handoff, and the action cannot guarantee that the user sends the message or places the call. +- Verify **Set Dark Mode Settings** with **From System**, explicit light and dark modes, and—if used—a Boolean variable (`true` for dark and `false` for light). diff --git a/docs/resources/control-flow/functions/utility-functions.md b/docs/resources/control-flow/functions/utility-functions.md index 108d7921f..42cbb7911 100644 --- a/docs/resources/control-flow/functions/utility-functions.md +++ b/docs/resources/control-flow/functions/utility-functions.md @@ -1,12 +1,21 @@ --- slug: /resources/functions/utility title: Utility Functions -description: Learn about the built-in utility functions available in FlutterFlow to enhance your app's UI logic. -tags: [Functions] +description: >- + Learn about the built-in utility functions available in FlutterFlow to enhance + your app's UI logic. +tags: + - FlutterFlow + - Resources + - Functions sidebar_position: 1 -keywords: [Built-in Functions, Backend Query, Backend Logic, Control Flow, FlutterFlow] +keywords: + - Built-in Functions + - Backend Query + - Backend Logic + - Control Flow + - FlutterFlow --- - # Utility Functions Utility functions are crucial for simplifying common tasks in app development, such as performing @@ -56,9 +65,8 @@ Here is a quick demo: height: 0, width: '100%' }}> - + +## Verify the delay + +Add visible actions immediately before and after **Wait (Delay)**, then run the flow in **Test Mode**. Confirm the duration uses milliseconds, the following action does not start early, navigation or disposal does not create an unintended side effect, and a variable duration cannot become negative or unexpectedly large. + +## Related documentation + +See [Periodic Action](/resources/time-based-logic/periodic-action) for a related FlutterFlow workflow. diff --git a/docs/resources/control-flow/user-interactivity/forms/form-actions/reset-form-field.md b/docs/resources/control-flow/user-interactivity/forms/form-actions/reset-form-field.md index 296e1d618..de0e37ff2 100644 --- a/docs/resources/control-flow/user-interactivity/forms/form-actions/reset-form-field.md +++ b/docs/resources/control-flow/user-interactivity/forms/form-actions/reset-form-field.md @@ -1,20 +1,48 @@ --- slug: /resources/forms/reset-form-field -title: Reset Form Field [Action] -tags: [Action, Form] -keywords: [FlutterFlow, reset form field, form action, user interface, mobile app development, input clearing, form management] -description: Learn how to add Reset Form Field action in your FlutterFlow app. +title: 'Reset Form Fields [Action]' +tags: + - FlutterFlow + - Resources + - Forms +keywords: + - FlutterFlow + - reset form field + - form action + - user interface + - mobile app development + - input clearing + - form management +description: Learn how to add the Reset Form Fields action in your FlutterFlow app. sidebar_position: 1 +last_verified: 2026-09-02 --- -# Reset Form Field [Action] +# Reset Form Fields [Action] -The **Reset Form Field** action allows you to reset values in form widgets. This is especially useful for clearing previously entered data and giving users a clean slate. +The **Reset Form Fields** action resets selected widgets to their initial values. It supports Dropdown, ChoiceChips, Checkbox, CheckboxGroup, RadioButton, TextField, Switch, and Pincode fields that are available in the current page or through its child components. For example, after a form is successfully submitted, you can use this action to clear the input fields—making it easy for users to enter new information for another submission. ![reset-form-field](imgs/reset-form-field.avif) +To configure it: + +1. Open the triggering widget's **Actions** tab and add an action. +2. Under **Widget/UI Interactions**, open **Reset Form Fields** and choose the field type. +3. Select one or more compatible fields of that type. +4. Run the flow in **Test Mode** or a deployed build and confirm each field returns to its configured initial value. + +Dynamic form fields are not selectable targets. Resetting a field also does not undo a database write or another side effect that already occurred. + :::info -You can also reset form fields that are inside the components. +You can also reset supported form fields inside child components. ![reset-form-field-component](imgs/reset-form-field-component.avif) -::: \ No newline at end of file +::: + +:::note +This action does not execute in Preview Mode. Use **Test Mode**, **Run Mode**, or a deployed build for verification. +::: + +## Related documentation + +See [Set Form Field Action](/resources/forms/set-form-field) for a related FlutterFlow workflow. diff --git a/docs/resources/control-flow/user-interactivity/forms/form-actions/set-form-field.md b/docs/resources/control-flow/user-interactivity/forms/form-actions/set-form-field.md index 6d189b815..64561f32b 100644 --- a/docs/resources/control-flow/user-interactivity/forms/form-actions/set-form-field.md +++ b/docs/resources/control-flow/user-interactivity/forms/form-actions/set-form-field.md @@ -1,14 +1,25 @@ --- slug: /resources/forms/set-form-field -title: Set Form Field [Action] -tags: [Action, Form] -keywords: [FlutterFlow, set form field, form action, user interface, mobile app development, input prefill, form management] +title: 'Set Form Field [Action]' +tags: + - FlutterFlow + - Resources + - Forms +keywords: + - FlutterFlow + - set form field + - form action + - user interface + - mobile app development + - input prefill + - form management description: Learn how to add Set Form Field action in your FlutterFlow app. sidebar_position: 0 +last_verified: 2026-09-02 --- # Set Form Field [Action] -The **Set Form Field** action allows you to programmatically populate or update the value of any input widget—like a TextField, Dropdown, or other form elements—at runtime. This is especially useful when you want to quickly fill or modify user input fields based on user preferences (e.g., saved addresses) or pre-stored information. +The **Set Form Field** action programmatically updates a supported input widget at runtime. Supported targets include Dropdown, ChoiceChips, Checkbox, CheckboxGroup, RadioButton, TextField, Switch, Pincode, Slider, RatingBar, and CountController. This is useful when you want to populate or modify input from saved preferences, page parameters, state, or backend data. :::info[possible use cases] @@ -20,6 +31,8 @@ The **Set Form Field** action allows you to programmatically populate or update While adding the Set Form Field action, select the target widget (e.g., `TextField`) and assign a value—this could come from a variable like `fullName` in your backend, app state, or page parameters. +The selected value must match the target field's data type. Dynamically generated fields are not selectable targets, and a RatingBar target must be interactive. + ![set-form-field-action.avif](imgs/set-form-field-action.avif) If you need to update several widgets (such as a TextField and a Dropdown), use a separate Set Form Field action for each and specify the appropriate value. @@ -40,10 +53,24 @@ When **Focus Field When Set** is enabled, you can set one of the following **Cur - **Highlight**: Selects (highlights) the entire text, letting the user immediately overwrite it. - **Preserve**: Maintains the cursor location as it was (if any), which is useful when the user is already typing and only part of the text has changed. +For fields with a text controller, **Rebuild Type** controls whether the action also rebuilds the surrounding widget tree. Use **Rebuild** when other visible widgets depend on the new value; use **No Rebuild** when only the field needs to update. + ![focus-field-when-set](imgs/focus-field-when-set.avif) :::info You can also set form fields inside the current widget’s child component.

![set-form-field-component](imgs/set-form-field-component.avif) -::: \ No newline at end of file +::: + +:::note +This action does not execute in Preview Mode. Use **Test Mode**, **Run Mode**, or a deployed build for verification. +::: + +## Verify the field update + +Test the action with the target's minimum, maximum, empty, and null cases where applicable. Confirm the new value appears, focus and cursor placement match the selected option, dependent UI rebuilds when required, and a later **Reset Form Fields** action returns the field to its configured initial value. + +## Related documentation + +See [Reset Form Field Action](/resources/forms/reset-form-field) for a related FlutterFlow workflow. diff --git a/docs/resources/control-flow/user-interactivity/forms/form-triggers.md b/docs/resources/control-flow/user-interactivity/forms/form-triggers.md index 76b2da889..895411887 100644 --- a/docs/resources/control-flow/user-interactivity/forms/form-triggers.md +++ b/docs/resources/control-flow/user-interactivity/forms/form-triggers.md @@ -1,12 +1,28 @@ --- slug: /resources/forms/form-triggers title: Form Triggers -tags: [Form, Actions, Triggers] -keywords: [FlutterFlow, Form Triggers, User Interactivity, Dropdown, Slider, Toggle, TextField, On Selected, On Toggled, On Change, On Focus Change] -description: Learn how to use Form Triggers in FlutterFlow to create dynamic, interactive user experiences by responding to user input on widgets like dropdowns, sliders, toggles, and text fields. +tags: + - FlutterFlow + - Resources + - Forms +keywords: + - FlutterFlow + - Form Triggers + - User Interactivity + - Dropdown + - Slider + - Toggle + - TextField + - On Selected + - On Toggled + - On Change + - On Focus Change +description: >- + Form Triggers in FlutterFlow allow you to respond dynamically to user input on + widgets like dropdowns, sliders, toggles, and text fields. sidebar_position: 4 +last_verified: 2026-09-02 --- - # Form Triggers **Form Triggers** in FlutterFlow allow you to respond dynamically to user input on widgets like dropdowns, sliders, toggles, and text fields. Whether it’s selecting an option, toggling a switch, or typing in a field, these triggers help you create interactive, responsive experiences by executing actions based on user interaction. @@ -42,7 +58,7 @@ These triggers are especially useful when you want to conditionally execute diff - **Switch – Enable Dark Mode:** User toggles a Switch to enable Dark Mode. Action under the *On Toggled On* trigger sets the dark mode. - **Checkbox – Agree to Terms:** User checks a Checkbox labeled “I agree to the terms and conditions.” The *On Toggled On* trigger enables the Submit button. If the user unchecks it, the *On Toggled Off* trigger disables the button again. -- **CheckboxListTile – Select Notification Channels:** User checks or unchecks options like Email, SMS, or Push Notifications. Each toggle fires either *On Toggled O*n or *On Toggled Off* to update selected preferences in the backend. +- **CheckboxListTile – Select Notification Channels:** User checks or unchecks options like Email, SMS, or Push Notifications. Each toggle fires either *On Toggled On* or *On Toggled Off* to update selected preferences in the backend. ::: @@ -64,7 +80,7 @@ It’s ideal for enabling live form validations, updating app state as the user :::tip[Possible use cases] - **TextField – Enable Button When Email Is Entered:** As the user types in an email TextField, action under the *On Change* trigger checks if the input is a valid email. If it is, it enables the Continue button. -- **Pincode – Auto Submit When Complete:** When a user finishes entering a 6-digit code in a Pincode widget, action under the *On Change* trigger checks if the full code is entered and triggers form submission or a backend call. +- **Pincode – Update While Typing:** As the user enters a code, an action under *On Change* can update helper UI. Use the Pincode widget's **On Completed** trigger when an action should run only after the configured number of characters has been entered. ::: @@ -97,4 +113,12 @@ To use the **On Focus Change** trigger: 3. Choose **On Focus Change** from the list of available triggers. 4. Define the actions to trigger, such as showing helper text, validating input, or updating the UI based on focus. -![on-focus-change](imgs/on-focus-change.avif) \ No newline at end of file +![on-focus-change](imgs/on-focus-change.avif) + +## Read the current value + +Within a trigger's action flow, select **Widget State** and then the triggering form widget to read its current value. Treat **On Change** as a high-frequency event: avoid unnecessary backend requests on every keystroke, or add debouncing where the widget provides it. + +## Verify form triggers + +Run the page in **Test Mode** and exercise each transition twice. Confirm that **On Selected** runs after a value changes, toggle-on and toggle-off flows remain distinct, **On Change** receives the current text, **On Completed** waits for a complete PIN, and **On Focus Change** handles both gaining and losing focus using the current focus state. diff --git a/docs/resources/control-flow/user-interactivity/forms/form-validation.md b/docs/resources/control-flow/user-interactivity/forms/form-validation.md index 886ab8322..01c0390c0 100644 --- a/docs/resources/control-flow/user-interactivity/forms/form-validation.md +++ b/docs/resources/control-flow/user-interactivity/forms/form-validation.md @@ -1,16 +1,25 @@ --- slug: /resources/forms/form-validation title: Form Validation -tags: [Form, Validation, Error Handling] -keywords: [FlutterFlow, form validation, input validation, error handling, user interface, mobile app development, data integrity] +tags: + - FlutterFlow + - Resources + - Forms +keywords: + - FlutterFlow + - form validation + - input validation + - error handling + - user interface + - mobile app development + - data integrity description: Learn how to add Form Validation widget in your FlutterFlow app. sidebar_position: 2 +last_verified: 2026-09-02 --- - - # Form Validation -You can add validations to input fields by wrapping them inside the Form widget. The Form widget enables you to validate user inputs and display appropriate messages when validation criteria are not met. +You can validate supported input fields by placing them inside the **Form Validation** widget. The widget coordinates validation and displays the messages you configure when input does not meet the required criteria. For example, you could use it to check if a user has given a valid email and password. This makes it easy to handle user input and ensure that the data is correct before it is submitted to the server or stored locally. @@ -23,9 +32,8 @@ Let's see how to add a *Form* widget by building a signup example. Here's how it paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding height: 0, width: '100%'}}> - -

\ No newline at end of file +

+ +## Verify form validation + +Test every rule at its boundary: empty input, one character below and above length limits, valid and invalid pattern values, and required action-based fields. Confirm that invalid input blocks the submission path, each error message appears next to the intended field, auto-validation occurs at the expected time, and a valid submission runs exactly once. diff --git a/docs/resources/control-flow/user-interactivity/forms/form-widgets/checkbox.md b/docs/resources/control-flow/user-interactivity/forms/form-widgets/checkbox.md index 661a198aa..5874c17f6 100644 --- a/docs/resources/control-flow/user-interactivity/forms/form-widgets/checkbox.md +++ b/docs/resources/control-flow/user-interactivity/forms/form-widgets/checkbox.md @@ -1,11 +1,25 @@ --- slug: /resources/forms/checkbox title: Checkbox -tags: [Widgets, Form Elements] -keywords: [FlutterFlow, Checkbox, CheckboxGroup, CheckboxListTile, Multiple Choice] -description: Learn how to add Checkbox, CheckboxGroup, and CheckboxListTile widget in your FlutterFlow app. +tags: + - FlutterFlow + - Resources + - Forms +keywords: + - FlutterFlow + - Checkbox + - CheckboxGroup + - CheckboxListTile + - Multiple Choice +description: >- + Learn how to add Checkbox, CheckboxGroup, and CheckboxListTile widget in your + FlutterFlow app. +last_verified: 2026-09-02 --- # Checkbox + +Use **Checkbox** for one Boolean choice, **CheckboxListTile** when the label and control should be one tappable row, and **CheckboxGroup** when the user may select zero or more values from a list. Read the current value from **Widget State** and use **On Change** when another action must run after the selection changes. + In FlutterFlow, a checkbox is a versatile input widget used to capture binary choices from users, such as true/false or yes/no options. It is ideal for situations where you need to present users with options that can be individually selected or deselected. FlutterFlow provides three primary variations of the checkbox widget: **Checkbox**, [**CheckboxListTile**](#checkboxlisttile), and [**CheckboxGroup**](#checkboxgroup). Each of these widgets offers distinct features and use cases, making it easy to tailor your app's interface to your specific needs. :::tip[Widget State] @@ -25,9 +39,8 @@ Let's see how to add a checkbox widget and build an example that shows its value paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding height: 0, width: '100%'}}> - -

\ No newline at end of file +

+ +## Verify RadioButton behavior + +- Ensure the initial option exactly matches an available option. +- Keep option values unique, especially when they are created dynamically. +- Test selection changes, an empty options list, and any disabled state. +- Confirm the selected and unselected styles remain distinguishable in light and dark themes. +- Before saving or comparing the widget state, verify its type matches the destination field or condition. diff --git a/docs/resources/control-flow/user-interactivity/forms/form-widgets/switch.md b/docs/resources/control-flow/user-interactivity/forms/form-widgets/switch.md index 03e96616a..94cb9fef4 100644 --- a/docs/resources/control-flow/user-interactivity/forms/form-widgets/switch.md +++ b/docs/resources/control-flow/user-interactivity/forms/form-widgets/switch.md @@ -1,12 +1,21 @@ --- slug: /resources/forms/switch title: Switch -tags: [Widgets, Form Elements] -keywords: [FlutterFlow, Switch, SwitchListTile] +tags: + - FlutterFlow + - Resources + - Forms +keywords: + - FlutterFlow + - Switch + - SwitchListTile description: Learn how to add Switch and SwitchListTile widget in your FlutterFlow app. +last_verified: 2026-09-02 --- # Switch Widgets +Use **Switch** for one Boolean setting. Use **SwitchListTile** when the text and switch should form one tappable row. Read the current Boolean from **Widget State**, and use **On Change** when the new value must trigger an action. + In FlutterFlow, **Switch** widgets provide an intuitive way for users to toggle between two states, such as on/off or enabled/disabled. They are useful for settings, preferences, and other scenarios where a simple binary choice is required. FlutterFlow offers two primary switch widgets: [**Switch**](#switch) and [**SwitchListTile**](#switchlisttile). Each of these widgets provides unique features and use cases, making it easy to incorporate toggle functionality into your app's interface. ## Switch @@ -22,9 +31,8 @@ Let's see how to add a switch widget and build an example that shows its value o paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding height: 0, width: '100%'}}> - -

\ No newline at end of file +

+ +## Verify switch behavior + +- Test both on and off initial values and confirm the saved destination is Boolean. +- Test the disabled state and make it visually clear that the control is unavailable. +- If the value is loaded asynchronously, verify that the switch does not briefly display or save the wrong default. +- On SwitchListTile, confirm tapping the label and control produces the intended behavior and remains accessible. +- Test light, dark, Android, and iOS/adaptive styling when those targets are supported. diff --git a/docs/resources/control-flow/user-interactivity/forms/form-widgets/text-field.md b/docs/resources/control-flow/user-interactivity/forms/form-widgets/text-field.md index 4f6a1e877..1fcce7d4b 100644 --- a/docs/resources/control-flow/user-interactivity/forms/form-widgets/text-field.md +++ b/docs/resources/control-flow/user-interactivity/forms/form-widgets/text-field.md @@ -1,15 +1,28 @@ --- slug: /resources/forms/textfield title: TextField -tags: [Widget, TextField, Form] -keywords: [FlutterFlow, TextField, form input, user interface, mobile app development, Flutter widget, text input] +tags: + - FlutterFlow + - Resources + - Forms +keywords: + - FlutterFlow + - TextField + - form input + - user interface + - mobile app development + - Flutter widget + - text input description: Learn how to add TextField widget in your FlutterFlow app. +last_verified: 2026-09-02 --- import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; # TextField +Use **TextField** to collect editable text. Choose the keyboard, capitalization, obscuring, formatting, and validation rules for the data you actually expect; these settings improve input but do not replace validation and authorization in your backend. + The TextField widget allows users to enter text, numbers, and symbols in your app. You can use the TextField widget to build forms, send messages, dialogs, search, etc. :::tip[Widget State] @@ -25,9 +38,8 @@ Let's see how to add a TextField widget and see an example of displaying its val paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding height: 0, width: '100%'}}> -

+ +## Verify TextField behavior + +- Test empty, valid, invalid, minimum, maximum, pasted, and autofilled values. +- Treat input filtering as a typing aid, not validation. Validate again before submission and on the server for security-sensitive data. +- Confirm the keyboard type, capitalization, submit action, focus order, and autofill hint on real Android and iOS devices. +- For password fields, verify obscuring and reveal behavior and never log or persist the password in app state. +- If **Update Page on Change** or an **On Change** action performs expensive work, debounce the operation or move it to an explicit submit action. +- Test read-only, disabled, multiline, maximum-length, and error states with screen readers and large text. diff --git a/docs/resources/control-flow/user-interactivity/forms/forms.md b/docs/resources/control-flow/user-interactivity/forms/forms.md index 82489cb19..a87696961 100644 --- a/docs/resources/control-flow/user-interactivity/forms/forms.md +++ b/docs/resources/control-flow/user-interactivity/forms/forms.md @@ -1,16 +1,40 @@ --- slug: /resources/forms title: Forms Overview -tags: [Forms] -keywords: [FlutterFlow, forms, input fields, user interface, mobile app development, data collection, user interaction] -description: Learn how to work with Forms in FlutterFlow app. +tags: + - FlutterFlow + - Resources + - Forms +keywords: + - FlutterFlow + - forms + - input fields + - user interface + - mobile app development + - data collection + - user interaction +description: >- + Forms are a fundamental part of many applications, serving as the primary + method for users to input and submit data. sidebar_position: 0 +last_verified: 2026-09-02 --- +# Forms Overview - -# Forms Overview Forms are a fundamental part of many applications, serving as the primary method for users to input and submit data. Whether you're building a simple contact form or a complex multi-step survey, FlutterFlow provides a comprehensive set of tools to create, validate, and manage forms effectively. :::tip In this section, you'll learn how to add form widgets such as [**TextField**](form-widgets/text-field.md), [**Dropdown**](form-widgets/dropdown.md), [**RadioButton**](form-widgets/radiobutton.md), [**Checkbox Widgets**](form-widgets/checkbox.md) and add [**Validations**](form-validation.md) and [**set**](form-actions/set-form-field.md)/[**reset**](form-actions/reset-form-field.md) actions on these widgets. ::: + +Use a **Form Validation** widget when several inputs should be validated together. Individual input widgets expose their current values through **Widget State**; the form coordinates validation, but it does not save or submit values automatically. Add backend or state-update actions after validation succeeds. + +## Recommended form flow + +1. Place input widgets inside a **Form Validation** widget. +2. Configure required, length, or pattern rules on the form. +3. Add a **Validate Form** action to the submit control. +4. Put submission actions after validation, or branch on the validation result when **Terminate if Validation Fails** is disabled. +5. After a successful submission, use **Reset Form Fields** if the form should return to its initial state. + +Test valid, invalid, empty, loading, error, and repeat-submission cases in **Test Mode** or a deployed build. diff --git a/docs/resources/data-representation/app-state.md b/docs/resources/data-representation/app-state.md index f022f034a..6932377da 100644 --- a/docs/resources/data-representation/app-state.md +++ b/docs/resources/data-representation/app-state.md @@ -1,16 +1,28 @@ --- slug: /resources/data-representation/app-state title: App State -description: Learn how to effectively utilize App State Variables in FlutterFlow to maintain and manage global application states across all pages and components. -tags: [App State, FlutterFlow, Data Representation] +description: >- + Learn how to effectively utilize App State Variables in FlutterFlow to + maintain and manage global application states across all pages and components. +last_verified: 2026-09-01 +tags: + - FlutterFlow + - Resources + - Data sidebar_position: 5 -keywords: [App State, FlutterFlow, Data Representation] +keywords: + - App State + - FlutterFlow + - Data Representation + - store a global value in FlutterFlow app state +ai_queries: + - store a global value in FlutterFlow app state --- - - # App State -App state variables are specific variables that hold the current state of an application. They can be accessed and modified throughout the entire application across all pages and components. This type of variable can be useful for storing data that needs to be shared between different parts of the app, such as user preferences and authentication tokens. +App State variables hold values that need to be read or changed across pages and components. Good examples include a shopping cart, an onboarding-complete flag, or a user-selected display preference. + +Do not put API keys, passwords, access tokens, or other secrets in App State. Persisted values are stored on the user's device, and values can still be exposed while the app is running or making network requests. Use a backend or another purpose-built secret-management mechanism for secrets. ![app-state-variables.avif](../imgs/app-state-variables.avif) @@ -20,11 +32,11 @@ App state variables should not be used for temporary data that doesn't impact th ## App State Variables -Let’s see how you can manage the app state variable using an example of adding items to a cart in a shopping app. +Let’s see how you can manage the app state variable using an example of adding items to a cart in a shopping app. ### Create App State variable -Head over to the left-side navigation menu and follow the steps below to create a variable. +Open **App Values > App State** from the left-side navigation menu, then select **Add App State Variable**.
-
-2. Access the Enum values by navigating to the **Set from Variable** menu, then selecting **Enums > [your enum name] > Values**. +3. To assign one value, open **Set from Variable > Enums > [your enum name]** and select the value. When the destination expects a list, select **Values** to use all values from that enum. ![enums.avif](../imgs/enums.avif) :::tip[Naming Convention] When naming enums, always use **UpperCamelCase**, and for enum values, use **lowerCamelCase**, as recommended by the Dart Style Guide. To learn more, refer to the guide on **[Naming Variables & Functions](../../resources/style-guide.md)**. ::: + +In exported code, project enums are generated in `lib/backend/schema/enums/enums.dart`. A variable typed as one enum cannot accept a value from a different enum, even if both contain an element with the same name. diff --git a/docs/resources/data-representation/global-properties.md b/docs/resources/data-representation/global-properties.md index 0cd289197..dbfe8fffa 100644 --- a/docs/resources/data-representation/global-properties.md +++ b/docs/resources/data-representation/global-properties.md @@ -1,15 +1,24 @@ --- slug: /resources/data-representation/global-properties title: Global Properties -description: Discover the role of Global Properties in FlutterFlow, which provide universal access across all pages of your app to facilitate common tasks and enhance functionality. -tags: [Global Properties, FlutterFlow, Data Representation] +description: >- + Discover the role of Global Properties in FlutterFlow, which provide universal + access across all pages of your app to facilitate common tasks and enhance + functionality. +last_verified: 2026-09-01 +tags: + - FlutterFlow + - Resources + - Data sidebar_position: 7 -keywords: [Global Properties, FlutterFlow, Data Representation] +keywords: + - Global Properties + - FlutterFlow + - Data Representation --- - # Global Properties -Global properties are **built-in variable**s in FlutterFlow that you can use across all pages of your app. These properties are predefined by FlutterFlow, meaning you cannot create or modify them yourself. They are designed to help you perform common tasks efficiently, no matter what type of app you’re developing. +Global properties are **built-in variables** that FlutterFlow exposes through **Set from Variable**. You cannot create, rename, or update them. Their values come from the running app, device, router, authentication configuration, or project settings. For example, global properties can be used to redirect users to another page if they are not logged in or to enable specific functionality based on the platform your app is running on. @@ -25,7 +34,7 @@ Global properties are built-in variables exposed by FlutterFlow. You can't creat ## List of Global Properties -A list of all the available global properties is as follows: +The complete set of global properties is below. Some entries appear only when the corresponding project feature is enabled. - **Is User Logged In:** Indicates whether a user is currently logged into the app. Useful for providing exclusive features to registered users or adjusting UI elements based on login status. This property is only accessible if you have enabled authentication of any type. @@ -33,22 +42,29 @@ A list of all the available global properties is as follows: - **Current Device Location:** Returns the user's current location, ideal for updating their position on Google Maps or storing it in a backend database. [Check out examples](#current-device-location) on how to retrieve and save the current device location. -- **Link To Current Page:** Provides the [Deep Link](../../ff-concepts/navigation-routing/deep-dynamic-linking.md#deep-link) of the current page. +- **Link To Current Page:** Provides the [Deep Link](../../ff-concepts/navigation-routing/deep-dynamic-linking.md#deep-link) of the current page. It is available for routed projects when Firebase Dynamic Links is not enabled. - **Current Route Path**: Provides the route name of the currently active or visible page in your app. This property is especially helpful in scenarios where you want to adjust or block specific actions if the active page isn't the one you expect. For example, if you launch the app through a push notification, the home page might still run in the background, even if the notification directs you to a different page. Using this property, you can prevent unnecessary action triggers, such as On Page Load from the home page. See details on avoiding [this issue](https://github.com/FlutterFlow/flutterflow-issues/issues/2765#issuecomment-2598915946). - **Current Route Stack:** Returns a list of route names representing every active page in your app’s navigation stack. It’s helpful for understanding how many pages deep the user is and what sequence of pages they’ve visited. You may need this data to manage custom back navigation, breadcrumb displays, or logging analytics. For instance, in an e-commerce app, you could examine the route stack to see if the user arrived at the checkout page from a specific page and tailor your promotional messages or apply discount accordingly. - **Fraction of Screen Width:** Determines the proportional width of the device's screen. - **Fraction of Screen Height:** Determines the proportional height of the device's screen. -- **Screen Width:** Provides the total width of the current device's screen in pixels. -- **Screen Height:** Provides the total height of the current device's screen in pixels. +- **Screen Width:** Provides the current screen width in Flutter logical pixels. +- **Screen Height:** Provides the current screen height in Flutter logical pixels. - **Is Android:** Determines if the user is accessing the app on an Android device. See [example](#is-androidiosweb). - **Is iOS:** Determines if the user is accessing the app on an iOS device. See [example](#is-androidiosweb). - **Is Web:** Determines if the user is accessing the app through a web browser. See [example](#is-androidiosweb). - **Is Debug Mode:** Indicates if the app is currently running in debug mode, useful for displaying features or performing actions only during debugging. - **Is Dark Mode:** Checks if the app's current theme mode is set to dark. - **Is Light Mode:** Checks if the app's current theme mode is set to light. -- **Is On-Screen Keyboard Visible:** Checks if the on-screen or soft keyboard is visible. This is helpful in making UI adjustments if keyboard is visible on screen. See a [quick example](#is-on-screen-keyboard-visible). -- **Current Environment**: Returns the current [development environment](../../testing-deployment-publishing/development-environments/development-environments.md) value. +- **Is On-Screen Keyboard Visible:** Checks if the on-screen or soft keyboard is visible. This is helpful in making UI adjustments if keyboard is visible on screen. See a [quick example](#is-on-screen-keyboard-visible). +- **Current Environment**: Returns the current [development environment](../../testing-deployment-publishing/development-environments/development-environments.md) value. It appears when the project defines more than one environment. + +Availability rules to remember: + +- **Is User Logged In** requires an authentication configuration. +- **Current Route Path** requires routing. +- **Is Dark Mode** and **Is Light Mode** require dark mode in the project theme. +- **Current Device Location** causes the generated app to request location permission where required by the platform. :::tip[Generated Code] Learn more about the [**Generated Code**](../../generated-code/state-mgmt-gen-code.md#global-state) behind Global Properties. @@ -138,7 +154,7 @@ This property is used to get the current device location (aka geolocation). You You can use this property to get the user's current location to update on Google Maps or store it in the backend database. :::warning -At present, testing this property isn't possible in Test mode, but you can use the Run mode for this purpose. To run it on Android, iOS or desktop platforms, use [Local Run](../../testing-deployment-publishing/running-your-app/local-run.md). +Location depends on device or browser permission. Test this flow on each platform you support, handle denied permission, and provide a fallback when a location is unavailable. For device testing, use [Local Run](../../testing-deployment-publishing/running-your-app/local-run.md). ::: @@ -161,9 +177,8 @@ Here is an example of how you can retrieve the current device location: height: 0, width: '100%' }}> - +

To build such behavior, you can add [Conditional Visibility](../../resources/ui/widgets/widget-commonalities.md#conditional) on the bottom navigation. While adding, use the "Is On-Screen Keyboard Visible" that will hide the bottom navigation bar whenever the keyboard is displayed. Using "Is On-Screen Keyboard Visible" to hide bottom navigation -
- +
diff --git a/docs/resources/data-representation/overview.md b/docs/resources/data-representation/overview.md index 13430a47b..89c8a37b4 100644 --- a/docs/resources/data-representation/overview.md +++ b/docs/resources/data-representation/overview.md @@ -1,17 +1,28 @@ --- slug: /resources/data-representation -title: Overview -description: Explore the essentials of data representation in app development, focusing on the use of variables in FlutterFlow. -tags: [Data Representation, FlutterFlow, Variables] +title: Data Representation Overview +description: >- + Explore the essentials of data representation in app development, focusing on + the use of variables in FlutterFlow. +last_verified: 2026-09-01 +tags: + - FlutterFlow + - Resources + - Data sidebar_position: 0 -keywords: [Data Representation, FlutterFlow, Variables, Data Types, Global Data, Encapsulation] +keywords: + - Data Representation + - FlutterFlow + - Variables + - Data Types + - Global Data + - Encapsulation --- - # Overview -Data representation is a fundamental concept in app development. It refers to the methods and structures used to store and manipulate the data. The way data is structured can greatly influence how efficiently an app performs tasks. +Data representation describes how an app models, stores, reads, and changes values. In FlutterFlow, the main choices are a value's data type, where it comes from, and the scope in which it can be used. ## Variable -In FlutterFlow, variables are key to managing dynamic data, ensuring your app remains interactive and responsive. They enable you to capture user inputs, track changes, and share data across different parts of your app. +Variables store or expose values used by widgets and actions. State variables are user-defined and scoped to the app, page, or component. Other values can come from widget state, action outputs, backend queries, parameters, global properties, or constants. :::info Dig deeper into **[variables and variable scopes](variables.md)**. @@ -29,11 +40,11 @@ Learn more about primitive and composite data types in this [**detailed guide**] ## Data mutability -All variables in FlutterFlow are mutable. This means you can change their values at runtime based on user interactions or other events in your app. FlutterFlow also supports immutable data, such as [**Constants**](constants.md) that cannot be changed once they have been set. +User-defined App, Page, and Component State variables are mutable through their corresponding update actions. Parameters, action outputs, backend-query results, and Global Properties are values you read rather than state you update directly. [**Constants**](constants.md) are configured in the builder and cannot be reassigned by the running app. ## Global Properties -Global properties in FlutterFlow are built-in variables that you can use across your app, but they cannot be created or modified by users. Learn how to leverage these [**predefined properties**](global-properties.md) to simplify common tasks. +Global properties are built-in, read-only values supplied by FlutterFlow, such as the current time, platform, route, or screen size. Learn how to use these [**predefined properties**](global-properties.md). ## Encapsulation @@ -46,13 +57,13 @@ FlutterFlow supports the principles of encapsulation through its visual developm 1. **Custom Widgets and Components**: In FlutterFlow, you can create custom widgets or use built-in widgets that encapsulate specific functionalities. These widgets can include both logic and UI elements that are bundled together. For example, if you are creating a user profile page, you can create a custom component that includes the user's photo, name, and contact button. This component can be reused wherever a user profile needs to be displayed in the app, ensuring that changes to the profile layout or functionality are centralized within this widget. - + 2. **Backend Actions**: FlutterFlow allows you to define backend actions that can be called from different parts of your app. These actions can encapsulate complex logic, such as processing user input, interacting with databases, or calling external APIs. - + By defining such actions, you can manage how data is processed and passed around in your applications. This helps in maintaining a clear separation between the UI and business logic, which is a core principle of encapsulation. - + ### Benefits of Encapsulation in FlutterFlow - **Reusability**: Encapsulated components are reusable across different parts of the application without requiring duplication of widgets. - **Maintainability**: Changes to the application’s data handling or business logic can be made in a single place using action blocks rather than having to make widespread modifications across many actions. -- **Scalability**: Applications can grow more naturally and with less complexity when their components are well-encapsulated. \ No newline at end of file +- **Scalability**: Applications can grow more naturally and with less complexity when their components are well-encapsulated. diff --git a/docs/resources/data-representation/variables.md b/docs/resources/data-representation/variables.md index d03a3f205..51b7a1a0e 100644 --- a/docs/resources/data-representation/variables.md +++ b/docs/resources/data-representation/variables.md @@ -1,11 +1,21 @@ --- title: Variables -description: Variables +description: >- + Variables in FlutterFlow let you store and manage dynamic data, which is + essential for creating interactive and responsive applications. +last_verified: 2026-09-01 sidebar_position: 1 slug: /resources/data-representation/variables +tags: + - FlutterFlow + - Resources + - Data +keywords: + - Variables + - Data Representation + - Resources --- - -# Variable +# Variables Variables in FlutterFlow let you store and manage dynamic data, which is essential for creating interactive and responsive applications. By using variables, you can capture user inputs, track states, and manipulate data across different parts of your app. @@ -31,14 +41,14 @@ Variables are used in practically all areas of the app, from the user interface When creating variables in FlutterFlow, there are a few important considerations regarding their name, data type, nullability, and initial values. The specific _process_ for creating variables differs depending on whether you are working with App State, Page State, or Component State variables, and you can find detailed instructions linked below. ### Naming Variable -Start by giving your variable a meaningful and descriptive name that reflects its purpose. This name will be used throughout your app to reference the variable, so it's important to keep it clear and consistent with your naming conventions. +Start by giving your variable a meaningful and descriptive name that reflects its purpose. This name will be used throughout your app to reference the variable, so it's important to keep it clear and consistent with your naming conventions. :::tip[Recommended naming convention] -We recommend the `lowerCamelCase` naming convention for variables. Learn more about the **[recommended naming conventions](../style-guide.md)** used in FlutterFlow and Flutter projects. +We recommend the `lowerCamelCase` naming convention for variables. Learn more about the **[recommended naming conventions](../style-guide.md)** used in FlutterFlow and Flutter projects. ::: ### Assigning a Data Type to a Variable -Next, you need to select the appropriate data type for your variable. FlutterFlow offers several data types, such as **Text, Integer, Boolean,** or **String**. Refer to the **[Data Types guide](data-types.md)** to learn more about the available data types. +Next, select the appropriate data type. Common choices include **String**, **Integer**, **Double**, and **Boolean**; structured and integration-specific types appear only in compatible contexts. Refer to the **[Data Types guide](data-types.md)** for the full model and availability rules. Choosing the correct data type is crucial, as it determines how the variable can be used and what kind of data it can store. @@ -48,7 +58,7 @@ Enable the **Is List** toggle to indicate that this field should be of the **lis :::info[Example] -If the data type selected is `String` and the `Is List` toggle is enabled, FlutterFlow will create a **list of String variables**. This list can hold multiple string values, such as a list of city names. +If the selected data type is `String` and **Is List** is enabled, FlutterFlow creates one variable whose value is a list of strings. It can hold multiple values, such as a list of city names. ::: ### Nullable & Initial Value @@ -90,7 +100,7 @@ When setting variables via the **Set Variable** menu, you have the ability to ma For instance, you can: -- **[Concatenate or Combine Strings:](../control-flow/functions/utility-functions.md#combine-text)** Combine multiple text values into a single string. To learn how to manipulate strings before setting variables, see the [Utility Functions](../control-flow/functions/utility-functions.md#combine-text) guide. +- **[Concatenate or Combine Strings:](../control-flow/functions/utility-functions.md#combine-text)** Combine multiple text values into a single string. To learn how to manipulate strings before setting variables, see the [Utility Functions](../control-flow/functions/utility-functions.md#combine-text) guide. - **[Filter or Sort Lists](#list-options):** Organize or refine data in lists to display only what’s relevant or in a specific order. - [**Convert DateTime to UNIX:**](global-properties.md#current-time) Change a DateTime object into a UNIX timestamp for compatibility or calculation purposes. - [**Apply Conditional Logic:**](../control-flow/functions/conditional-logic.md) Use If/Then/Else statements to set different values based on specific conditions. @@ -109,8 +119,7 @@ The option **Map List Items** allows you to prepare a list of specific fields fr Here's an example of preparing a list of only cat names from Firebase documents (that contain other fields like name, age, and breed) and displaying them on dropdown. -
+
@@ -118,8 +127,7 @@ com/embed/744716b1b4d640bc8a18c2fc4c7a2a25?sid=2f642f76-4a6b-4f39-a62f-3cec58953 The **Filter List Items** option allows you to create a list of items based on specific criteria, generating a sublist of items that match. For example, you might want to create a list of users over a certain age from a larger user database or perhaps compile a list of products within a specific price range from an extensive inventory. -
+
@@ -135,13 +143,12 @@ If your list contains "native data types" (like numbers or strings), we can auto Here's an example of displaying random names in alphabetical order: -
+

-:::info[Reversing a list] -To reverse sort a list, first sort it using the sort option, then apply the listView's [reverse option](../ui/widgets/composing-widgets/list-grid.md#advanced-functionalities) for descending order. +:::info[Descending order] +In **Sort List Items**, set **Sort Order** to **Descending**. A ListView's [Reverse](../ui/widgets/composing-widgets/list-grid.md#advanced-functionalities) setting changes its layout and scroll direction; it is not a substitute for sorting the data. ::: For lists with [Custom Data Types](custom-data-types.md), you need to tell which field to use for sorting by specifying it in the **Sort Key**, and this field should be a standard data type that has a clear, natural way to be ordered. @@ -149,8 +156,7 @@ For lists with [Custom Data Types](custom-data-types.md), you need to tell which Here's how you can display a list of items (of the custom data type 'Product') in order, sorted by their price.

-
+
@@ -160,8 +166,7 @@ This option helps you create a list with unique items, such as extracting distin Here's an example of displaying a list of unique cat breeds: -
+

@@ -169,8 +174,7 @@ To get a list of unique items from a list of custom data type, first map the lis

-
+
@@ -178,23 +182,20 @@ com/embed/92db0dff32734c44b6f2b31e2538ec99?sid=7c632af2-c196-43c3-8ad0-9d61570a0 Choose the **Number of Items** option if you want to get the count of the total elements in the list. -
+
#### Item at Index -The **Item at Index** option allows you to access a specific item by its position in the list. For instance, you could retrieve the third item from a list of customer names, or select the fifth product in a catalog list. This is especially useful in scenarios where the order of items carries significance, such as fetching the latest entry in a time-ordered log, or simply when you need to pinpoint a specific item without filtering through the entire list. +The **Item at Index** option accesses an item by its zero-based position: index `0` is the first item, index `1` is the second, and so on. Ensure the index is within the list's bounds before relying on the result. -
+
#### Is Set and Not Empty To determine, if any value is present in the list or if the list is not empty, choose the **Is Set And Not Empty** option. For example, it can be used to check if a search query returned any results or to verify that a data collection process has successfully captured entries. -
+
diff --git a/docs/resources/projects/how-to-collaborate-on-projects.md b/docs/resources/projects/how-to-collaborate-on-projects.md index d7f319681..96a8703fd 100644 --- a/docs/resources/projects/how-to-collaborate-on-projects.md +++ b/docs/resources/projects/how-to-collaborate-on-projects.md @@ -1,14 +1,26 @@ --- slug: /resources/projects/collaboration title: Collaborate on Projects -description: Learn how to collaborate effectively on projects in FlutterFlow, including best practices for teamwork and project management. -tags: [Collaboration, Project Management] +description: >- + Learn how to collaborate effectively on projects in FlutterFlow, including + best practices for teamwork and project management. +tags: + - FlutterFlow + - Resources + - Projects toc_max_heading_level: 5 sidebar_position: 3 -keywords: [Collaboration, FlutterFlow, Project Management] +keywords: + - Collaboration + - FlutterFlow + - Project Management + - invite teammates to collaborate on a FlutterFlow project +ai_queries: + - invite teammates to collaborate on a FlutterFlow project --- +# Collaborate on Projects -In FlutterFlow you can share projects with your entire organization (team), with individual users within your organization, or external users. +In FlutterFlow you can share projects with your entire organization (team), with individual users within your organization, or external users. ## Sharing a Project with Team @@ -16,8 +28,8 @@ To share a project with team members, use the **Share with team** dropdown in th ![share_with_team.png](imgs/share_with_team.png) -- **Team project:** A project associated with your team and automatically visible to all team members. When a project is a Team Project, team members are automatically added as Editors. You can specifically designate team members as Viewers, but you cannot remove them. -- **Restricted team project:** A project associated with your team but only visible to specific team members who are added directly. After selecting this option, you’ll need to manually choose the team members you want to share the project with. +- **Team project:** A project associated with your team and automatically visible to all team members. When a project is a Team Project, team members are automatically added as Editors. You can specifically designate team members as Viewers, but you cannot remove them. +- **Restricted team project:** A project associated with your team but only visible to specific team members who are added directly. After selecting this option, you’ll need to manually choose the team members you want to share the project with. - **Personal project:** A project not associated with any team, where editing capabilities depend on the type of personal plan you have. :::info @@ -44,7 +56,7 @@ You can add users as Read Only users to any project regardless of your pricing p - If a user isn't already a FlutterFlow user, we will send them an invite email. Their status will be shown as Pending until they create an account. ::: -To add an external user as a collaborator as an Editor to a project, you first need to purchase a collaborator pass. +To add an external user as a collaborator as an Editor to a project, you first need to purchase a collaborator pass. To purchase a collaborator pass, go to the [My Teams](https://app.flutterflow.io/team) page and, under the **Collaborator Passes** section, click **Add Pass** and complete the checkout process. Once the pass is created, enter the user email and select the project (Team Project or Restricted Team Project) you’d like to grant them access to. @@ -59,9 +71,8 @@ To purchase a collaborator pass, go to the [My Teams](https://app.flutterflow.io paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding height: 0, width: '100%'}}> -

+ +## Related documentation + +See [What is a Project?](/resources/projects) for a related FlutterFlow workflow. diff --git a/docs/resources/projects/settings/general-settings.md b/docs/resources/projects/settings/general-settings.md index 4f7c8c501..231d95d7c 100644 --- a/docs/resources/projects/settings/general-settings.md +++ b/docs/resources/projects/settings/general-settings.md @@ -1,12 +1,22 @@ --- slug: general-settings title: General Settings -tags: [Project, Assets] -keywords: [project name, package name, asset, download settings, assets, splash screen, launcher icon, adaptive icon] +tags: + - FlutterFlow + - Resources + - Projects +keywords: + - project name + - package name + - asset + - download settings + - assets + - splash screen + - launcher icon + - adaptive icon description: Learn how to configure general settings for your FlutterFlow app. sidebar_position: 0 --- - # General Settings General Settings serve as the control center for configuring essential aspects of your app. @@ -127,9 +137,9 @@ To add the app launcher icon: 3. Under the **Launcher Icon** section, click **Upload Image**. 4. Use the **Unset** dropdown menu to select from images already uploaded to Project Media/Assets. 5. [Download the project](../../../ff-concepts/advanced/flutterflow-cli/exporting-projects.md) and run the following command in your terminal to generate the launcher icon: - + `flutter pub run flutter_launcher_icons:main` - + 6. [Run your app](../../../testing-deployment-publishing/running-your-app/run-your-app.md) on a real device or emulator to see the app launcher icon. ### Android Adaptive Icon @@ -146,9 +156,9 @@ Here are the steps to add adaptive icons: 1. Upload the **Foreground Icon**. If you use the online tool, you'll find it inside the `IconKitchen-Output > android > res > mipmap-xxxhdpi > ic_launcher_foreground.png`. 2. For **Background Type**, you can either set the **Color** or **Image**. Use a color that aligns with your app's branding for a cohesive look. 3. [Download the project](../../../ff-concepts/advanced/flutterflow-cli/exporting-projects.md) and run the following command in your terminal to generate the launcher icon: - + `flutter pub run flutter_launcher_icons:main` - + 4. [Run your app](../../../testing-deployment-publishing/running-your-app/run-your-app.md) on a real device or emulator to see the app launcher icon. ![adaptive-icons](imgs/adaptive-icons.avif) @@ -160,8 +170,6 @@ See the following resources for more information on Android adaptive icons. #### Create Adaptive Icon - [Create app icons in Android Studio](https://developer.android.com/studio/write/create-app-icons#create-adaptive) -- [Figma template](https://material.uplabs.com/posts/adaptive-icon-sticker-sheet) (requires login) -- [Affinity Designer template](https://cyrilmottier.com/2017/07/06/adaptive-icon-template/) - [Bjango templates](https://github.com/bjango/Bjango-Templates) include adaptive icons - [Adobe XD template](https://github.com/faizmalkani/adaptive-icon-template-xd) diff --git a/docs/resources/projects/settings/project-apis.md b/docs/resources/projects/settings/project-apis.md index 6bc759e59..3fe8b199b 100644 --- a/docs/resources/projects/settings/project-apis.md +++ b/docs/resources/projects/settings/project-apis.md @@ -1,9 +1,19 @@ --- slug: project-apis title: Project APIs -tags: [APIs, Projects] -keywords: [projects, apis, refactor code] +tags: + - FlutterFlow + - Resources + - Projects +keywords: + - projects + - apis + - refactor code sidebar_position: 5 +description: >- + The FlutterFlow Project APIs allow you to programmatically read, write, and + validate YAML configuration files through REST endpoints. +last_verified: 2026-09-02 --- import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; @@ -12,6 +22,8 @@ import TabItem from '@theme/TabItem'; The FlutterFlow **Project APIs** allow you to programmatically read, write, and validate YAML configuration files through REST endpoints. Using these APIs, you can automate project management tasks, integrate continuous integration and delivery (CI/CD) workflows, and apply bulk configuration updates without manual interactions with the FlutterFlow user interface. +For a safe update, export the current file, preserve its version information, change only the intended fields, call **Validate Project YAML**, and apply the update only after validation succeeds. Fetch the project again before writing if another person or automation may have edited it. + :::warning The Project API is currently in beta and may undergo changes that could affect functionality or compatibility. @@ -91,7 +103,7 @@ https://api-enterprise-europe.flutterflow.io/v2/ ``` - + ## Authentication All API endpoints require authentication using a Bearer token. You'll need to include your FlutterFlow API token in the Authorization header of each request. See [how to get the API Token](../../../accounts-billing/account-management.md#how-do-i-generate-an-api-token). @@ -100,6 +112,10 @@ All API endpoints require authentication using a Bearer token. You'll need to in Authorization: Bearer YOUR_API_TOKEN_HERE ``` +:::warning[Protect project data and tokens] +An API token can provide access to private project configuration. Keep it in a secret manager or protected environment variable, never commit it, and never include it in screenshots, logs, public bug reports, or AI prompts. Project YAML can contain proprietary configuration and references to services; handle exports as confidential project data. +::: + ## API Endpoints Below is a list of available API endpoints with their methods and usage descriptions. @@ -116,7 +132,7 @@ Below is a list of available API endpoints with their methods and usage descript Before you read or update project files, you need to know what YAML files are available. This endpoint returns a full list of file names associated with your FlutterFlow project. -#### Endpoint +#### Endpoint `GET /listPartitionedFileNames` #### Query Parameters @@ -129,7 +145,7 @@ Before you read or update project files, you need to know what YAML files are av "reason":null, "value":{ "versionInfo": { - "partitionerVersion": 6, + "partitionerVersion": 6, "projectSchemaFingerprint": "abc123" }, "fileNames": [ @@ -243,7 +259,7 @@ You can download specific or all YAML configuration files from your FlutterFlow - `fileName` (optional): Specific file to export (without extension). If not provided, all files are exported. #### Response -Returns a zip file encoded as a base64 string. You will need to manually decode this base64 data into a downloadable .zip file. To do so, copy the value of `projectYamlBytes` and then you can use online tools such as [base64.guru](https://base64.guru/converter/decode/file) or [b64encode.com](https://b64encode.com/tools/base64-to-zip/) to convert and download the files. +Returns a ZIP archive encoded as a base64 string in `projectYamlBytes`. Decode it locally; do not paste a private project export into an online converter. For example, after extracting only the base64 value to a protected local file named `project-yaml.b64`, run `base64 --decode project-yaml.b64 > project-yaml.zip` on systems that support that command. Your operating system may use a different base64 flag. ```jsx { @@ -261,12 +277,12 @@ Returns a zip file encoded as a base64 string. You will need to manually decode #### Example Usage ```jsx -# Export all YAML files +## Export all YAML files curl -X GET \ 'https://api.flutterflow.io/v2/projectYamls?projectId=your-project-id' \ -H 'Authorization: Bearer YOUR_API_TOKEN' -# Export specific file +## Export specific file curl -X GET \ 'https://api.flutterflow.io/v2/projectYamls?projectId=your-project-id&fileName=ad-mob' \ -H 'Authorization: Bearer YOUR_API_TOKEN' @@ -274,7 +290,7 @@ curl -X GET \ ### Validate Project YAML -You must validate the YAML content before applying changes to ensure it's properly formatted and contains valid values. +Validate the complete replacement content before applying changes. A successful syntax validation does not prove that the update matches your intent, so review the diff and test the project afterward. #### Endpoint `POST /validateProjectYaml` @@ -292,7 +308,7 @@ You must validate the YAML content before applying changes to ensure it's proper - In the `fileContent` object, you must provide the **entire content** of the file. - The YAML content must be passed as a **single-line string** with correct formatting and appropriate escaping for new lines and indentation. For example, in the following `fileContent` object, you see the actual multiline YAML content, which is not allowed ❌. - + ```jsx { "projectId": "ecommerce-flow-app-ie7nl6", @@ -308,7 +324,7 @@ You must validate the YAML content before applying changes to ensure it's proper persisted: false" } ``` - + Now, here’s how the YAML content should be passed (i.e., as single line string ✅). ```jsx @@ -343,11 +359,11 @@ You must validate the YAML content before applying changes to ensure it's proper ```jsx curl -X POST \ 'https://api.flutterflow.io/v2/validateProjectYaml' \ - -H 'Authorization: Bearer YOUR_API_KEY' \ + -H 'Authorization: Bearer YOUR_API_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "projectId": "your-project-id", - "fileKey": "ad-mob", + "fileKey": "ad-mob", "fileContent": "showTestAds: false" }' ``` @@ -372,7 +388,7 @@ This endpoint allows you to overwrite existing files in your FlutterFlow project :::info - In the `fileKeyToContent` object, you must provide the **entire content** of the file. - The YAML content must be passed as a **single-line string** with correct formatting and appropriate escaping for newlines and indentation. For example, in the following `fileKeyToContent` object, you see the actual multiline YAML content, which is not allowed ❌. - + ```jsx { "projectId": "ecommerce-flow-app-ie7nl6", @@ -434,16 +450,15 @@ You can download and use - - - - - - diff --git a/docs/resources/ui/pages/page-elements.md b/docs/resources/ui/pages/page-elements.md index c27cb3883..5ed8cdd8a 100644 --- a/docs/resources/ui/pages/page-elements.md +++ b/docs/resources/ui/pages/page-elements.md @@ -3,8 +3,18 @@ title: Page Elements slug: /resources/ui/pages/scaffold sidebar_position: 2 toc_max_heading_level: 5 +description: >- + Page elements in FlutterFlow are the key elements that define the structure + and functionality of each page in your app. +tags: + - FlutterFlow + - Resources + - UI +keywords: + - Page Elements + - Scaffold + - Pages --- - # Page Elements Page elements in FlutterFlow are the key elements that define the structure and functionality of each page in your app. Understanding these elements is crucial for building intuitive and effective user interfaces. From navigational elements like the **AppBar** and Drawer to interactive components like **Floating Action Buttons (FABs)**, each element plays a specific role in shaping the user experience. @@ -41,7 +51,7 @@ FlutterFlow Page**](#) section. ## AppBar **AppBar** is a widget that displays a toolbar at the top of the screen, typically used for -branding, navigation, and actions related to the current screen. It supports a title and icons, +branding, navigation, and actions related to the current screen. It supports a title and icons, and offers customization with a variety of styles and functionalities. The AppBar is divided into the following sections: @@ -61,7 +71,7 @@ The AppBar is divided into the following sections: height: 0, width: '100%' }}> - + +## Verify the result + +Run the page and confirm that headings, emphasis, and links render instead of appearing as Markdown source. If **Selectable** is enabled, select and copy part of the text. Test every link and sanitize or validate user-provided Markdown and destinations before displaying them. -
+## Related documentation +See [Launch URL](/concepts/navigation/launch-url) for URL formats and platform considerations. diff --git a/docs/resources/ui/widgets/built-in-widgets/media-display.md b/docs/resources/ui/widgets/built-in-widgets/media-display.md index a1b5763ec..9a2ea1c0e 100644 --- a/docs/resources/ui/widgets/built-in-widgets/media-display.md +++ b/docs/resources/ui/widgets/built-in-widgets/media-display.md @@ -1,12 +1,25 @@ --- title: MediaDisplay slug: media-display -tags: [Components, Base Elements] -keywords: [Media, Image, Video, Widget, Base Elements] +tags: + - FlutterFlow + - Resources + - UI +keywords: + - Media + - Image + - Video + - Widget + - Base Elements description: Learn how to add MediaDisplay widget in your FlutterFlow app. +last_verified: 2026-09-02 --- -# MediaDisplay -The **MediaDisplay** widget in FlutterFlow automatically detects the type of media fetched from a URL and adjusts the widget accordingly. For instance, if the URL returns an image, the widget will behave as an Image widget. +# Media Display +The **MediaDisplay** widget chooses an image or video presentation from a media URL. Runtime detection uses the URL's file extension: MP4 and MPEG video paths use the video player, while other paths use the image presentation. Query parameters do not affect the extension check. + +:::warning +MediaDisplay does not inspect the downloaded response body or its HTTP `Content-Type`. Use a direct URL with a recognizable file extension. Extensionless URLs, unsupported video formats, and redirect URLs that hide the extension may be treated as images. +::: This versatility allows you to easily present various types of media within your app. For example, it can be integrated into scrollable widgets like [ListView](../../widgets/composing-widgets/list-grid.md#listview-widget) for displaying activity feeds or [GridView](../../widgets/composing-widgets/list-grid.md#gridview-widget) for presenting photos and videos together. @@ -19,9 +32,8 @@ Let's build an example of using the MediaDisplay widget inside the ListView and paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding height: 0, width: '100%'}}> - +## Verify the interaction + +Run the page on web or desktop with a mouse. Enter and leave the child's visible bounds and confirm that **On Mouse Enter**, **On Mouse Exit**, the cursor, and any conditional visibility update exactly once per boundary crossing. Then test the same feature on a touch device and confirm that the non-hover alternative remains usable. diff --git a/docs/resources/ui/widgets/built-in-widgets/pincode.md b/docs/resources/ui/widgets/built-in-widgets/pincode.md index ee20d7303..3990d7b8e 100644 --- a/docs/resources/ui/widgets/built-in-widgets/pincode.md +++ b/docs/resources/ui/widgets/built-in-widgets/pincode.md @@ -1,9 +1,19 @@ --- slug: pincode title: PinCode -tags: [PinCode, Form Elements] -keywords: [FlutterFlow, PinCode, Form Widget, App Development, Input Field, Flutter] +tags: + - FlutterFlow + - Resources + - UI +keywords: + - FlutterFlow + - PinCode + - Form Widget + - App Development + - Input Field + - Flutter description: Learn how to add the PinCode widget in your FlutterFlow app. +last_verified: 2026-09-02 --- # PinCode @@ -18,8 +28,8 @@ Before diving into form widgets, check out our guide on [**Widget States**](../. To add a PinCode widget: 1. Open the [Widget Palette](../../../../intro/ff-ui/widget-palette.md) and locate the **PinCode** widget under the **Base Elements** tab. You can drag it into your desired location or add it directly from the widget tree or canvas area. -2. To increase the pin length (number of values users can enter), move to the properties panel, see the **Pin Length** property, and enter the value. **Note**: You can only set this value up to 8. -3. If you are using this widget to get a secret PIN from users, you can obscure it with a special character. To do so, enable the **Obscure Text** toggle and select the **Obscuring Character** among the *,-,?, and •. +2. Set **Pin Length** to a value from 3 through 8. A newly added PinCode uses six characters. +3. To hide entered characters visually, enable **Obscure Text** and select `*`, `-`, `?`, or `●` as the **Obscuring Character**. 4. You can also enable/disable the **Hint Text** toggle and select the **Hint Character** displayed when you haven't entered anything.
-
-

\ No newline at end of file +

+ +## Verify the result + +Run the page and test progress values `0`, `0.5`, and `1`. Confirm that the fill, optional text, animation, colors, and selected shape match the configured values. For dynamic progress, also test loading and error states so the interface does not imply completion while the underlying task has failed. + +## Related documentation + +See [Widget State](/concepts/state-management/widget-state) for reading widget values and [File Handling](/concepts/file-handling) for upload and download workflows that can use a progress indicator. diff --git a/docs/resources/ui/widgets/built-in-widgets/ratingbar.md b/docs/resources/ui/widgets/built-in-widgets/ratingbar.md index c8b40d869..c597fdbca 100644 --- a/docs/resources/ui/widgets/built-in-widgets/ratingbar.md +++ b/docs/resources/ui/widgets/built-in-widgets/ratingbar.md @@ -1,12 +1,20 @@ --- slug: ratingbar title: RatingBar -tags: [RatingBar, Form Elements] -keywords: [FlutterFlow, RatingBar, Form Widget, App Development, Input Field, Flutter] +tags: + - FlutterFlow + - Resources + - UI +keywords: + - FlutterFlow + - RatingBar + - Form Widget + - App Development + - Input Field + - Flutter description: Learn how to add RatingBar in your FlutterFlow app. +last_verified: 2026-09-02 --- - - # RatingBar The RatingBar widget is used to show a rating or collect ratings from users (this is an interactive RatingBar). For example, you can use the RatingBar widget inside an e-commerce app to show ratings for a product. @@ -26,9 +34,8 @@ Here's an example of how you can use the RatingBar widget in your project: paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding height: 0, width: '100%'}}> -

+ +## Verify the interaction + +Run the page and select several ratings. Confirm that **Widget State** and the **On Change** action receive the selected value. Turn off **Interactive** and verify that the same bar no longer accepts input and displays the configured **Rating**, including any intended partial icon. + +## Related documentation + +See [Widget State](/concepts/state-management/widget-state) for using the selected value and [Forms](/resources/forms) for validating and submitting form data. diff --git a/docs/resources/ui/widgets/built-in-widgets/signature.md b/docs/resources/ui/widgets/built-in-widgets/signature.md index d3516accf..aae079524 100644 --- a/docs/resources/ui/widgets/built-in-widgets/signature.md +++ b/docs/resources/ui/widgets/built-in-widgets/signature.md @@ -1,11 +1,18 @@ --- slug: signature title: Signature -tags: [Form Elements, Components] -keywords: [Signature, Form Element, Component, Widget] +tags: + - FlutterFlow + - Resources + - UI +keywords: + - Signature + - Form Element + - Component + - Widget description: Learn how to add Signature widget in your FlutterFlow app. +last_verified: 2026-09-02 --- - # Signature The signature widget allows you to capture a signature. This widget tracks your finger or mouse pointer on a screen and draws the line accordingly on a signature pad. @@ -17,16 +24,15 @@ You can use this widget to get the user consent on an agreement or contract in d Here's an example of how you can add the Signature widget to your project: 1. First, drag the **Signature** widget from the **Form Elements** tab (in the Widget Panel) or add it directly from the widget tree. -2. Move to the properties panel, scroll down to the **Signature** section and adjust the **width** and **height** of the widget. +2. In **Properties > Signature**, set the canvas width and height, **Pen Color**, **Pen Stroke Width**, visible **Background Color**, and **Export Background Color** used in the saved PNG. A new Signature is 120 pixels high, uses the available width, and exports on a white background.
-
-

\ No newline at end of file +

diff --git a/docs/resources/ui/widgets/built-in-widgets/slider.md b/docs/resources/ui/widgets/built-in-widgets/slider.md index 6b0ce00e1..c9c6ca10c 100644 --- a/docs/resources/ui/widgets/built-in-widgets/slider.md +++ b/docs/resources/ui/widgets/built-in-widgets/slider.md @@ -1,12 +1,20 @@ --- slug: slider title: Slider -tags: [Slider, Form Elements] -keywords: [FlutterFlow, Slider, Form Widget, App Development, Input Field, Flutter] -description: Learn how to add Slider in your FlutterFlow app. +tags: + - FlutterFlow + - Resources + - UI +keywords: + - FlutterFlow + - Slider + - Form Widget + - App Development + - Input Field + - Flutter +description: The Slider widget is used to select a single value from a range of values. +last_verified: 2026-09-02 --- - - # Slider The Slider widget is used to select a single value from a range of values. You define the min and max value for the slider, and users can choose the value between the specified range by dragging the slider thumb (sliding circle). @@ -26,9 +34,8 @@ Let's build an example of using the Slider widget and retrieve its value in a Te paddingBottom: 'calc(35.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding height: 0, width: '100%'}}> - +
@@ -117,9 +126,8 @@ Here's how it looks when completed: height: 0, width: '100%' }}> - +
-4. Now, inside the *StickyHeader* *Content* section, add the **ListView** with a **Container** +4. Now, inside the *StickyHeader* *Content* section, add the **ListView** with a **Container** inside to display the list of matching contacts. 1. On this ListView, generate dynamic children from a variable that holds all the contacts. But while doing so, filter the list and extract only matching contacts using [Inline Function](../../../../resources/control-flow/functions/utility-functions.md#inline-function-code-expressions). 2. Now you can display the contact's details, such as name, inside the UI. -
+
+ +## Header overlap + +Enable **Sticky Header Properties > Allow Header Overlap** when a later sticky header may move over an earlier one. It is disabled on a newly added StickyHeader. Test the visual stacking and background opacity carefully when enabling it. + +## Verify the layout +Run the page, scroll through the entire parent, and confirm that the header sticks only while its associated content is in view. Test more than one StickyHeader, with and without overlap, and check that no nested scroll area traps touch or wheel input. diff --git a/docs/resources/ui/widgets/built-in-widgets/swipeablestack.md b/docs/resources/ui/widgets/built-in-widgets/swipeablestack.md index 803ad4738..42ce2c67a 100644 --- a/docs/resources/ui/widgets/built-in-widgets/swipeablestack.md +++ b/docs/resources/ui/widgets/built-in-widgets/swipeablestack.md @@ -1,10 +1,17 @@ --- slug: swipeable-stack title: SwipeableStack -tags: [Layout Elements] +tags: + - FlutterFlow + - Resources + - UI description: Learn how to add SwipeableStack widget in your FlutterFlow project. +keywords: + - SwipeableStack + - Swipeable Stack + - Built In Widgets +last_verified: 2026-09-02 --- - # SwipeableStack The SwipeableStack is a widget designed to stack cards or content layers that users can swipe in any direction. It is commonly used in dating apps like Tinder for profile browsing. @@ -14,9 +21,8 @@ The SwipeableStack is a widget designed to stack cards or content layers that us paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding height: 0, width: '100%'}}> - + +## Default behavior and verification + +A new Tooltip uses text content, opens below its child, uses Tap for touch input, waits 100 milliseconds, and remains visible for 1500 milliseconds. It has 4 pixels of offset and padding, an 8-pixel corner radius, elevation 4, and a visible tail. + +Run the page with mouse, keyboard, and touch input. Confirm that the Tooltip does not hide required information, can be dismissed, remains on screen long enough to read, and is not the only way to discover an essential control label. Enable **Show Tooltip on Focus** when keyboard users need the same cue. diff --git a/docs/resources/ui/widgets/built-in-widgets/transform.md b/docs/resources/ui/widgets/built-in-widgets/transform.md index de6754c39..cd53bac5f 100644 --- a/docs/resources/ui/widgets/built-in-widgets/transform.md +++ b/docs/resources/ui/widgets/built-in-widgets/transform.md @@ -1,7 +1,18 @@ --- -tags: [Base Elements] +tags: + - FlutterFlow + - Resources + - UI +title: Transform +description: >- + The widget applies graphic transformations such as skew (or tilt), rotate, + scale, and translate (or slide) to its child widget. +keywords: + - Transform + - Built In Widgets + - Widgets +last_verified: 2026-09-02 --- - # Transform The `Transform` widget applies graphic transformations such as skew (or tilt), rotate, scale, and translate (or slide) to its child widget. You could use this widget in combination with animations to build visually engaging apps. @@ -12,17 +23,16 @@ The `Transform` widget applies graphic transformations such as skew (or tilt), r To add a Transform widget to your app: -1. First, click on the **+ Add Widget**, drag the **Transform** widget from the **Base Elements** +1. First, click on the **+ Add Widget**, drag the **Transform** widget from the **Base Elements** tab, or add it directly from the widget tree. 2. Add a child widget inside the Transform widget that you want to transform. -3. By default, the transformation applied to a child widget is the **Skew** transformation. This type of transformation allows you to tilt the child widget, i.e., top and bottom or the left and right sides no longer remain to be parallel. To add/customize tilt to the child widget: +3. A new Transform starts as **Rotate** with an angle of 0 degrees, so it does not initially change the child. To apply a skew instead, set **Transform Type** to **Skew**, then configure it: - 1. Select the **Transform** widget and move to the properties panel. - 5. To add tilt in the horizontal direction, find the **Skew X** property and use the slider or directly enter the value into the box. The positive value will move the top side to the left and the bottom side to the right. - 8. To add tilt in the vertical direction, use the **Skew Y** property. The positive value will move the left side in an upward direction and the right side in a downward direction. - 11. The negative value will move the sides in the opposite direction. -4. Optional: To change the position of the origin (a center of the transform widget), you can use the **Transform Orgin and Alignment** options. + 1. Select the **Transform** widget and open the Properties panel. + 2. Set **Skew X** for horizontal skew and **Skew Y** for vertical skew. These values are angular inputs; small values produce the most predictable result. + 3. Use negative values to reverse the direction. +4. For Scale, Skew, or Rotate, use **Transform Origin and Alignment** to change the pivot alignment and its horizontal or vertical offset. Translate does not expose origin controls because it moves the whole painted child.
-
+## Layout, hit testing, and animation + +Transform changes how its child is painted; the parent still lays out the widget at its original size and position. Leave enough surrounding space to avoid visual clipping or overlap, and test taps after translating, rotating, or scaling an interactive child. + +**Implicit Animation** is available for Scale and Rotate. Enabling it defaults to an ease-in-out curve over 300 milliseconds and animates later value changes. Animated Scale is uniform and uses **Scale X** as its scale value; keep Scale X and Scale Y equal when animation is enabled. Skew and Translate do not support Transform's implicit-animation option. + +## Verify the result + +Run the page and test the transform at its minimum, maximum, and neutral values. Confirm the pivot, direction, clipping, hit target, and any implicit animation. For responsive screens, test multiple sizes because a visual translation does not reserve new layout space. +

* For **Translate** type: @@ -132,9 +149,8 @@ To change the transform type, select the **Transform** widget, move to the prope height: 0, width: '100%' }}> - +## Verify generated children + +Run the page in **Test Mode** with an empty list, a one-item list, and a list longer than **Max Items**. Confirm that the empty state is handled, each rendered child uses the corresponding current item, actions operate on that same item, and the item count respects the limit. diff --git a/docs/resources/ui/widgets/composing-widgets/list-grid.md b/docs/resources/ui/widgets/composing-widgets/list-grid.md index 5b14f5d57..4adf7b4a0 100644 --- a/docs/resources/ui/widgets/composing-widgets/list-grid.md +++ b/docs/resources/ui/widgets/composing-widgets/list-grid.md @@ -1,8 +1,20 @@ --- title: Lists & Grids -tags: [Layout Elements] +tags: + - FlutterFlow + - Resources + - UI sidebar_position: 2 +description: >- + In FlutterFlow, and are versatile widgets designed for displaying lists and + grids of elements, respectively. +keywords: + - Lists & Grids + - List Grid + - Composing Widgets --- +# Lists & Grids + In FlutterFlow, `ListView` and `GridView` are versatile widgets designed for displaying lists and grids of elements, respectively. Both are highly customizable and optimized for dynamic content, making them essential for any app that requires scrolling through a collection of items such as images, text, or interactive elements. ## ListView Widget diff --git a/docs/resources/ui/widgets/composing-widgets/rows-column-stack.md b/docs/resources/ui/widgets/composing-widgets/rows-column-stack.md index 81ed09962..06894023c 100644 --- a/docs/resources/ui/widgets/composing-widgets/rows-column-stack.md +++ b/docs/resources/ui/widgets/composing-widgets/rows-column-stack.md @@ -1,12 +1,21 @@ --- -title: Rows, Column & Stack +title: 'Rows, Column & Stack' sidebar_position: 1 -tags: [Layout Elements, Widgets] -keywords: [Rows, Columns, Stack, Layout, Widgets] +tags: + - FlutterFlow + - Resources + - UI +keywords: + - Rows + - Columns + - Stack + - Layout + - Widgets slug: /resources/ui/widgets/composing-widgets/rows-column-stack +description: >- + In Flutter, , , and are fundamental layout widgets that help you structure the + UI by organizing other widgets in different visual arrangements. --- - - # Rows, Column & Stack In Flutter, `Rows`, `Columns`, and `Stacks` are fundamental layout widgets that @@ -19,7 +28,7 @@ want to place elements side by side across the screen. - **Column**: A `Column` organizes its child widgets vertically, stacking them from top to bottom. This is ideal for placing elements that need to appear in a vertical -sequence, such as a list of messages in a chat app or entries in a form. +sequence, such as a list of messages in a chat app or entries in a form. - **Stack**: A `Stack` layers its child widgets on top of each other, allowing for overlapping elements. In a `Stack`, widgets can be positioned absolutely relative to the @@ -115,16 +124,16 @@ orientations, ensuring a robust and flexible UI. ## Expansion & Flex (for Row & Column) -When widgets are placed inside a Row or Column in a layout, they gain access to an additional -property called **Expansion** & **Flex**. This property controls how a widget behaves in terms of taking up +When widgets are placed inside a Row or Column in a layout, they gain access to an additional +property called **Expansion** & **Flex**. This property controls how a widget behaves in terms of taking up available space within its parent Row or Column. -#### Expanded +#### Expanded -The Expansion properties are as follows: +The Expansion properties are as follows: -- **Default:** Make the widget NOT fill space along the main axis (horizontal for Row, vertical +- **Default:** Make the widget NOT fill space along the main axis (horizontal for Row, vertical for Column), therefore taking the minimum space required by its contents. - **Flexible:** Allow the widget to take up to the available space along @@ -141,21 +150,21 @@ but otherwise will be constrained to the available width. :::tip[Using Expanded & Flexible in an Example] ![expanded.png](../built-in-widgets/imgs/expanded.png) -1. **Default Behavior:** Here, you see two child widgets displayed next to each other, each +1. **Default Behavior:** Here, you see two child widgets displayed next to each other, each occupying only the necessary space to show its content without any expansion. -2. **Expanded Widget Usage:** The first child widget (highlighted in red) is wrapped with an +2. **Expanded Widget Usage:** The first child widget (highlighted in red) is wrapped with an **Expanded** widget. This causes it to take up all the remaining space in the container after accounting for the space required by the other widgets. Here, the first child stretches to fill all the extra space, pushing the other widgets to the side or shrinking them to their minimum size. 3. **All Expanded Widgets:** In this example, all child widgets are set to **Expanded**. This configuration divides the container's space equally among all child widgets, regardless of their intrinsic size. Each widget stretches to fill an equal portion of the container. -4. **All Flexible Widgets:** In the last example, each child widget is wrapped with a **Flexible** - widget. +4. **All Flexible Widgets:** In the last example, each child widget is wrapped with a **Flexible** + widget. This allows the widgets to expand to fill the available space but unlike **Expanded**, they can also shrink below their allocated space if necessary, based on the flex factors and the minimum space required by each widget. If all have the same flex factor, they will divide the space equally but are able to shrink if the content size demands less space. ::: -Let's understand Flexible concept with another example: +Let's understand Flexible concept with another example: :::tip[Flexible Concept] @@ -163,7 +172,7 @@ Let's understand Flexible concept with another example: - In the left image, Child 2 (in purple) and Child 3 (in green) retain their intrinsic sizes due to **default settings**, causing their content to appear cut off when the container's width is limited. They cannot adapt to smaller spaces, leading to potential content clipping. This highlights the limitations of default settings in confined spaces where dynamic resizing would improve content visibility. -- In contrast, the right image uses the **Flexible widget** for Child 2 and Child 3, allowing them to +- In contrast, the right image uses the **Flexible widget** for Child 2 and Child 3, allowing them to adjust dynamically to the container's width constraints. Instead of sticking to their original sizes, these widgets can shrink or expand, making the layout responsive and ensuring content remains visible and well-aligned, regardless of screen size changes. This adaptability is crucial for maintaining accessibility and visual coherence in diverse display environments. ::: @@ -175,8 +184,8 @@ adjust dynamically to the container's width constraints. Instead of sticking to Additionally, you can utilize Flex factors to determine the flexibility of a widget within its parent container. A Flex factor is an integer assigned to a child widget, indicating its proportional size compared to other children in the same parent. The space a child occupies is determined by its Flex factor in relation to the total Flex factors of all siblings in the layout. :::info[Default Behavior] -If no flex factor is provided, the child will not expand to fill extra -space +If no flex factor is provided, the child will not expand to fill extra +space in the parent container. It will occupy only the space required for its content unless styled otherwise. ::: @@ -185,49 +194,48 @@ When you assign a flex factor, the widget can expand to fill any available space :::tip[Flex Example] ![flex.png](../built-in-widgets/imgs/flex.png) -- Child 2 (purple) with a higher Flex factor (8) consistently occupies a larger portion of space, +- Child 2 (purple) with a higher Flex factor (8) consistently occupies a larger portion of space, showing how a higher number increases the space allocation relative to other widgets. -- Child 3 (green) has varying Flex factors (1 and 4), illustrating how increasing the Flex +- Child 3 (green) has varying Flex factors (1 and 4), illustrating how increasing the Flex factor allows the widget to occupy more space, albeit still less than Child 2 due to its lower Flex factor. ::: -Find a video tutorial about Expanded & Flexible: +Find a video tutorial about Expanded & Flexible: -
+
## Scrollability Scrollability for **Row or Column** widgets in FlutterFlow determines whether the content within these layouts can extend beyond the visible boundaries of the screen or container, enabling horizontal or vertical scrolling: -- **Allow Scrolling:** When enabled, this allows the content to exceed the device or parent +- **Allow Scrolling:** When enabled, this allows the content to exceed the device or parent container’s screen limits, making the overflow content accessible through scrolling. -- **Do Not Allow Scrolling:** If disabled, the content that exceeds the boundaries of the screen or -its parent container will not be accessible through scrolling. This setting forces the content - to fit within the available visible space, hiding overflow content or potentially causing layout +- **Do Not Allow Scrolling:** If disabled, the content that exceeds the boundaries of the screen or +its parent container will not be accessible through scrolling. This setting forces the content + to fit within the available visible space, hiding overflow content or potentially causing layout issues. :::tip[Generated Code] -In the generated Flutter code, enabling scrollability simply involves wrapping the Row or Column -in a `SingleChildScrollView()`. This widget adjusts its child's size and position based on the +In the generated Flutter code, enabling scrollability simply involves wrapping the Row or Column +in a `SingleChildScrollView()`. This widget adjusts its child's size and position based on the incoming constraints and the scrolling movement, effectively managing overflow by introducing scrollable behavior. ::: ## Spacing -- **Items Spacing:** This field sets the space between each child widget within the Row or - Column. You can specify a static numerical value that determines the pixel spacing between +- **Items Spacing:** This field sets the space between each child widget within the Row or + Column. You can specify a static numerical value that determines the pixel spacing between adjacent children or set it from a variable. :::tip[Items Spacing vs Padding] Prefer “Items Spacing” set on the parent row or column instead of padding on individual elements. This ensures consistency, especially on non-dynamically generated lists. ::: -- **Apply to Start & End:** When toggled on, this applies the specified item spacing to the +- **Apply to Start & End:** When toggled on, this applies the specified item spacing to the beginning and the end of the Row or Column. This effectively adds padding at the start and end of the layout in addition to between the items. -- **Start Spacing and End Spacing:** These properties allow for additional specific spacing at - the start and end of the Row or Column, respectively. This is useful for fine-tuning the layout to ensure content is visually balanced within the container or to provide clear margins. \ No newline at end of file +- **Start Spacing and End Spacing:** These properties allow for additional specific spacing at + the start and end of the Row or Column, respectively. This is useful for fine-tuning the layout to ensure content is visually balanced within the container or to provide clear margins. diff --git a/docs/resources/ui/widgets/intro-widgets.md b/docs/resources/ui/widgets/intro-widgets.md index 456047b41..20fbdf5d1 100644 --- a/docs/resources/ui/widgets/intro-widgets.md +++ b/docs/resources/ui/widgets/intro-widgets.md @@ -1,32 +1,39 @@ --- title: Introduction to Widgets -description: Introduction to Widgets +description: Widgets are the building blocks of your app's user interface in FlutterFlow. slug: /resources/ui/widgets -keywords: [Widgets] +keywords: + - Widgets + - Introduction to Widgets + - Ui sidebar_position: 0 +tags: + - FlutterFlow + - Resources + - UI +last_verified: 2026-09-02 --- - - # Introduction to Widgets -Widgets are the building blocks of your app's user interface in FlutterFlow. Each widget represents a fundamental UI element that contributes to the overall layout and functionality of your app. In FlutterFlow, you create your app's UI by combining basic widgets like **Text, Button** and **Container** with more complex, multi-child widgets like **Rows, Column, Lists**. +Widgets are the building blocks of your app's user interface in FlutterFlow. Each widget represents a UI element that contributes to the layout or behavior of your app. You create an interface by combining basic widgets such as **Text**, **Button**, and **Container** with layout and multi-child widgets such as **Row**, **Column**, **ListView**, and **GridView**. Understanding the parent-child relationship between widgets is crucial, as it forms the foundation of the [**Widget Tree**](#widget-tree), which defines the structure and hierarchy of your app's UI. ## Types of Widgets in FlutterFlow -- **Built-in Widgets**: You can choose from a variety of built-in widgets in FlutterFlow. These are discussed throughout this section. +- **Built-in Widgets**: You can choose from a variety of built-in widgets in FlutterFlow. These are discussed throughout this section. -- **[Components](../components/creating-components.md)**: You can also build your own reusable widgets, or - Components by assembling multiple widgets using FlutterFlow’s drag-and-drop interface. +- **[Components](../components/creating-components.md)**: You can also build your own reusable widgets, or + Components by assembling multiple widgets using FlutterFlow’s drag-and-drop interface. - **[Custom Widgets](../../../ff-concepts/adding-customization/custom-widgets.md)**: For scenarios where more complex functionalities are required, FlutterFlow - allows you to develop your own Custom Widgets using code. + allows you to develop your own Custom Widgets using code. - **[Theme Widgets](../../../ff-concepts/design-system/design-system.md#theme-widgets)**: Themed widgets can be reused across your app, making it easy to update styles universally. If you decide to change any properties, such as color schemes or fonts, you can update the theme widget instead of modifying each widget individually. ## Widget Tree -The Widget Tree is a structural representation of how widgets—ranging from [atomic elements](../overview.md) like Text and Button to more [complex molecules and organisms](../overview.md)—organized within a Page. It outlines the parent-child relationships that define the layout and functionality of your UI. This hierarchy is similar to the concept of atomic design, where atoms and molecules combine to form more complex structures, ultimately creating a cohesive interface. + +The Widget Tree is a structural representation of how widgets—ranging from [atomic elements](../overview.md) like Text and Button to more [complex molecules and organisms](../overview.md)—are organized within a Page. It shows the parent-child relationships that define the layout and functionality of your UI. This hierarchy is similar to atomic design, where atoms and molecules combine to form more complex structures and, ultimately, a complete interface. :::info[WIDGET TREE BREAKDOWN] ![tree.png](../imgs/tree.png) @@ -66,6 +73,7 @@ complete pages. In FlutterFlow, we have the following categories of widgets: +- **Commonly Used Elements:** A convenient collection of widgets you use frequently. This section can overlap with the categories below. - [Layout Elements](#layout-elements) - [Base Elements](#base-elements) - [Page Elements](#page-elements) @@ -80,12 +88,12 @@ Common layout elements include: | Widget | Description | Example | |---------------|---------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------| -| **Row** | Arrange its child widgets horizontally | | -| **Column** | Organizes its child widgets vertically. | | -| **Stack** | Layers its child widgets on top of each other, allowing for overlapping elements. | | -| **Container** | Provides a box model for a single child widget, with optional padding, margins, borders, box shadow and background color. | | +| **Row** | Arrange its child widgets horizontally | Row Example in FlutterFlow | +| **Column** | Organizes its child widgets vertically. | Col Example 1 in FlutterFlow | +| **Stack** | Layers its child widgets on top of each other, allowing for overlapping elements. | Stack Example in FlutterFlow | +| **Container** | Provides a box model for a single child widget, with optional padding, margins, borders, box shadow and background color. | Cont Example in FlutterFlow | -Find the entire list on this [**index page**](/tags/layout-elements). +Find the entire list on this [**index page**](/resources/ui/widgets#layout-elements). #### Base Elements @@ -96,12 +104,12 @@ Examples include: | Widget | Description | Example | |---------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------| -| **[Text](basic-widgets/text.md)** | Displays a string of text and allows you to customize fonts, sizes, and styles. | | -| [**Image**](basic-widgets/image.md) | Displays image. | | -| [**Icon**](basic-widgets/icons.md) | Displays icon. | | -| [**Button**](basic-widgets/button.md) | A widget meant to trigger actions and take users to another flow in the app. It can be styled with different colors, borders, and text | | +| **[Text](basic-widgets/text.md)** | Displays a string of text and allows you to customize fonts, sizes, and styles. | Text Example in FlutterFlow | +| [**Image**](basic-widgets/image.md) | Displays image. | Example in FlutterFlow | +| [**Icon**](basic-widgets/icons.md) | Displays icon. | Icon Example in FlutterFlow | +| [**Button**](basic-widgets/button.md) | A widget meant to trigger actions and take users to another flow in the app. It can be styled with different colors, borders, and text | Button Example in FlutterFlow | -Find the entire list on this [**index page**](/tags/base-elements). +Find the entire list on this [**index page**](/resources/ui/widgets#base-elements). #### Page Elements @@ -126,7 +134,11 @@ Examples include: | **Radio Button** | Allows users to select one option from a set. | Radio Button Example | | **Dropdown** | Provides a menu with multiple options where users can select one. | Dropdown Example | -Find the entire list on this [**index page**](/tags/form-elements). +Find the entire list on this [**index page**](/resources/ui/widgets#form-elements). Each category in FlutterFlow serves distinct purposes, helping you design both the appearance and functionality of your app more efficiently. + +## Verify a widget hierarchy + +Select a widget on the canvas and locate the same widget in the **Widget Tree**. Move or nest it, then confirm its indentation and parent change in the tree. Run the page in **Test Mode** to verify that the resulting layout and interactions match the hierarchy you created. diff --git a/docs/resources/ui/widgets/widget-commonalities.md b/docs/resources/ui/widgets/widget-commonalities.md index 6e085a1d3..6ed8bda64 100644 --- a/docs/resources/ui/widgets/widget-commonalities.md +++ b/docs/resources/ui/widgets/widget-commonalities.md @@ -1,12 +1,26 @@ --- title: Common Widget Properties -tags: [Widgets] -keywords: [Common Widget Properties, Visibility, Opacity, Padding, Alignment, Testing Value Key, Width and Height, Color Picker, Bulk Edits, Unsplash Images, UI Builder Display Value, Border Settings] +tags: + - FlutterFlow + - Resources + - UI +keywords: + - Common Widget Properties + - Visibility + - Opacity + - Padding + - Alignment + - Testing Value Key + - Width and Height + - Color Picker + - Bulk Edits + - Unsplash Images + - UI Builder Display Value + - Border Settings description: Learn how to control common widget properties in FlutterFlow sidebar_position: 6 +last_verified: 2026-09-02 --- - - # Common Widget Properties When working with widgets in FlutterFlow, you'll encounter properties and features that are common across multiple widget types. Below is a detailed overview of such properties. @@ -44,6 +58,8 @@ For example, you might create two separate navigation menus: The **Opacity** property controls how transparent or visible a widget appears. It accepts a value between 0 and 1, where 0 means fully transparent, 1 is fully opaque, and 0.5 results in semi-transparency. +Setting opacity to `0` makes a widget visually transparent but does not remove its layout space. Use **Conditional** visibility when the widget should not participate in the layout while hidden. + This property enables a wide range of creative UI effects, such as translucent buttons, overlay highlights, or smooth theme transitions. When **Animated Opacity** is enabled, any changes to the opacity value are smoothly animated based on the specified duration and curve, enhancing visual appeal and user experience. @@ -67,9 +83,8 @@ You can choose from two options: paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding height: 0, width: '100%'}}> - -

\ No newline at end of file +

+ +## Verify common properties + +Run the page in **Test Mode** at mobile, tablet, and desktop widths. Confirm that conditional and responsive visibility behave independently, percentage dimensions scale with the screen, opacity does not unexpectedly leave unusable layout space, dynamic colors have a valid fallback, and testing keys uniquely identify their intended widgets. diff --git a/docs/resources/ui/widgets/widget-properties.md b/docs/resources/ui/widgets/widget-properties.md index 4152a1bdf..2665c7b58 100644 --- a/docs/resources/ui/widgets/widget-properties.md +++ b/docs/resources/ui/widgets/widget-properties.md @@ -2,8 +2,19 @@ title: Widget Properties slug: /resources/ui/widgets/properties sidebar_position: 2 +description: >- + In FlutterFlow, the Properties Panel on the right helps you configure and + manage your widgets. +tags: + - FlutterFlow + - Resources + - UI +keywords: + - Widget Properties + - Properties + - Widgets +last_verified: 2026-09-02 --- - # Properties Panel In FlutterFlow, the Properties Panel on the right helps you configure and manage your widgets. It opens when you click on a widget or [component](../components/intro-components.md) in the [**Widget Tree**](../widgets/intro-widgets.md#widget-tree). @@ -16,9 +27,8 @@ Here's a quick demo showing how to add a widget to the canvas, which opens the w height: 0, width: '100%' }}> - - diff --git a/docs/testing-deployment-publishing/publishing/pre-checks-publishing.md b/docs/testing-deployment-publishing/publishing/pre-checks-publishing.md index f4d3b254b..488b64604 100644 --- a/docs/testing-deployment-publishing/publishing/pre-checks-publishing.md +++ b/docs/testing-deployment-publishing/publishing/pre-checks-publishing.md @@ -1,12 +1,20 @@ --- slug: /deployment/pre-checks-before-publishing title: Pre-checks Before Publishing -description: Ensure your app is ready for launch with this detailed guide on essential pre-publishing checks. -tags: [Pre-checks, Publishing, Deployment] +description: >- + Ensure your app is ready for launch with this detailed guide on essential + pre-publishing checks. +tags: + - FlutterFlow + - Deployment +last_verified: 2026-09-02 sidebar_position: 1 -keywords: [Pre-checks, Publishing, Deployment, FlutterFlow] +keywords: + - Pre-checks + - Publishing + - Deployment + - FlutterFlow --- - # Pre-checks Before Publishing This page outlines the important steps and checks to be made before publishing your app. These steps are crucial to ensure that your app works as expected, meets platform guidelines, and to gather preliminary feedback. @@ -19,11 +27,13 @@ Here’s a comprehensive list of these prechecks: 3. **Optimizations & Enhancements**: Improve performance by implementing [optimization and enhancement](../../intro/ff-ui/toolbar.md#project-suggestions) suggestions. Ensure that images are properly sized, consider using higher compression for assets, and remove unused assets and custom widgets. These will help improve your app's speed and size. 4. **User Interface:** Check UI consistency across different screen sizes and resolutions using the [Canvas Size](../../intro/ff-ui/canvas.md) option. 5. **Accessibility Checks**: Add semantic labels to make the app more accessible to users with disabilities by providing meaningful descriptions. -6. **Security Measures**: Make sure all data handling practices comply with legal standards, including GDPR if applicable. Use HTTPS for all network connections and ensure that sensitive data is encrypted. +6. **Security and Privacy**: Test least-privilege database and storage rules, authentication and authorization, private APIs, secret handling, account deletion, abuse controls, dependency risk, and data retention. HTTPS and encryption are necessary but do not replace authorization or secure backend design. Complete accurate privacy disclosures, consent flows, data-safety forms, and deletion mechanisms for every SDK and data flow. 7. **Compliance with Store Guidelines**: Review the submission guidelines for [Apple’s App Store](https://developer.apple.com/app-store/review/guidelines/) and [Google Play Store](https://play.google/developer-content-policy/). Check for any specific requirements such as app metadata, privacy policies, and minimum functionality. 8. **Localization and Internationalization**: If your app targets users in multiple countries, consider [adding multi-language](../../ff-concepts/localization-accessibility/localization.md) support. 9. **License and Third-Party Attributions**: Adhere to licenses and include necessary attributions for third-party libraries and assets. 10. **Prepare Marketing Assets**: Prepare all the necessary marketing assets, such as screenshots, app icons, and promotional text. You can easily [generate screenshots](../publishing/pre-checks-publishing.md#generate-screenshots) right within FlutterFlow. +11. **Release Operations**: Verify production environment selection, package or bundle ID, version and build number, signing, billing mode, store products, OAuth redirect URLs, deep links, push credentials, analytics, crash reporting, alerts, backups, rollback, and support contact details. +12. **Adversarial and Failure Testing**: Test slow or offline networks, denied permissions, expired sessions, duplicate taps and webhooks, interrupted purchases, empty and error states, large data, rate limits, and owner versus non-owner access on release builds. --- @@ -45,9 +55,8 @@ Let's explore how to generate screenshots for your app: height: 0, width: '100%' }}> - - \ No newline at end of file + diff --git a/docs/testing-deployment-publishing/publishing/web-publishing.md b/docs/testing-deployment-publishing/publishing/web-publishing.md index 4a0309c18..ad3896ecd 100644 --- a/docs/testing-deployment-publishing/publishing/web-publishing.md +++ b/docs/testing-deployment-publishing/publishing/web-publishing.md @@ -1,12 +1,23 @@ --- slug: /deployment/web-publishing title: Web Publishing -description: Discover how to effortlessly publish your applications on the web with FlutterFlow. This guide covers everything from enabling web support to deploying your app and adding custom domains. -tags: [Web Publishing, Deployment] +description: >- + FlutterFlow supports web publishing, allowing you to build and publish web + applications in addition to your mobile apps. +tags: + - FlutterFlow + - Deployment sidebar_position: 2 -keywords: [Web Publishing, Deployment, FlutterFlow, Custom Domains] +keywords: + - Web Publishing + - Deployment + - FlutterFlow + - Custom Domains + - publish a FlutterFlow app to the web +ai_queries: + - publish a FlutterFlow app to the web +last_verified: 2026-09-02 --- - # Web Publishing FlutterFlow supports web publishing, allowing you to build and publish web applications in addition to your mobile apps. This guide provides details on how to use FlutterFlow for web publishing. From enabling web support and making design adjustments to deploying your app and adding custom domains. @@ -40,24 +51,24 @@ To add platform support, navigate to the **Setting and Integrations > Project Se :::info -Enabling web support automatically enables +Enabling web support automatically enables [**deep linking**](../../ff-concepts/navigation-routing/deep-dynamic-linking.md) for your project. This helps in creating URLs for every page of your app. ::: #### Advanced Web Settings -1. **Use CanvasKit**: Enabling this option can provide high-quality graphics and text rendering on web platforms. +1. **Use CanvasKit**: Enabling this option can provide high-quality graphics and text rendering on web platforms. 2. **CORS Proxy for Images (Optional)**: When using CanvasKit, some images can be blocked from loading if the server is not configured to allow loading them from other websites. This happens because Flutter web uses WebGL for rendering, which requires access to raw image data and is subject to browser security restrictions called [Cross-Origin Resource Sharing (CORS)](https://docs.flutter.dev/platform-integration/web/web-images#cross-origin-resource-sharing-cors). Choose the appropriate option based on where your images are hosted: - **None**: If you are only loading images from your Firebase Storage, select this option and configure Firebase Storage for web access. FlutterFlow automatically excludes Firebase Storage images from CORS proxy requirements. - + - **Deploy with Firebase**: If images are hosted on external servers (not Firebase Storage) *but you use Firebase for your app*, choose this option. FlutterFlow will automatically deploy a regional CORS proxy function to your Firebase project for optimal performance. Simply click the **Deploy** button that appears below this option. - - - **Custom Proxy URL**: If you're not using Firebase or prefer to manage your own CORS proxy, specify your custom proxy URL here. If you don't have one, you can create one using services like [cors-anywhere](https://github.com/Rob--W/cors-anywhere) or CloudFlare Workers. + + - **Custom Proxy URL**: If you're not using Firebase or prefer to manage your own proxy, specify a proxy you operate and secure. Allowlist trusted origins and destinations, block private or internal network targets, limit response size and content types, authenticate where appropriate, and rate-limit requests. Do not send user credentials or private URLs through a public shared CORS proxy. :::warning **Performance Note**: Using a CORS proxy adds a network hop for external images, which may slightly increase loading times. For best performance, host images on Firebase Storage or a CORS-enabled CDN when possible. @@ -81,7 +92,7 @@ If you're experiencing image loading issues on web: 1. **Check browser console**: Look for CORS-related error messages 2. **Verify image sources**: Ensure external image servers allow cross-origin requests 3. **Test proxy configuration**: Verify your custom proxy URL is accessible and functioning -4. **Firebase Storage setup**: Confirm Firebase Storage rules allow public read access for web +4. **Firebase Storage setup**: Configure bucket CORS for the deployed origin and confirm authenticated Storage Rules allow only the intended objects. Do not make private files public merely to fix CORS. ### 2. Make design adjustments (optional) @@ -117,13 +128,13 @@ In this step, you must provide general information about your web app by followi Inside the **General Information** section, enter the following details: - **Site URL**: You can define the *Site URL* by adding the subdomain, for example, *mywebapp.flutterflow.app*. You can only change the subdomain, i.e., the part before *flutterflow.app*. - + :::warning - You can remove or change the existing subdomain by simply entering the new one and hitting the publish button. Note that when you change your subdomain, it only takes effect the next time you deploy. - Old addresses can stop working anytime and be given to another user. - - There is a limit on the number of subdomains you can register per user. *Paying users can register up to 20 subdomains*. You will receive an in-app warning if you are approaching the limit. + - Subdomain limits depend on the current plan. Use the limit shown in FlutterFlow and the current pricing page rather than relying on a hard-coded quota. ::: - + - **SEO Title**: This appears in social sharing previews and search results. - **Site Description**: A text that you would like to appear in the social sharing preview card and search results. - **Page Title**: This appears in the browsers tab for all pages of your app. @@ -134,7 +145,7 @@ Inside the **General Information** section, enter the following details: - **Show Watermark**: By default, a button with 'Built in FlutterFlow' text appears as a watermark at the bottom right side of your page. To remove, disable the **Show watermark** toggle. - **Allow Showcasing**: If enabled, we may feature your project on our website. - **Allows Search Engine Indexing**: This is to let people discover your site via search engines. -- **Enabling PWA**: Enabling this can provide an app-like experience right in the browser. PWA app can be installed on the device, supports offline functionality, sends push notifications, and can be accessed without the need to go through an app store. +- **Enabling PWA**: Enables installable-app metadata and supporting web behavior. Actual installation, offline behavior, background features, and push notification support vary by browser and platform and still require compatible app logic, service-worker behavior, permissions, and testing. - **Use CanvasKit**: Enabling this can provide high-quality graphics and text rendering on web platforms. CanvasKit can be used as an alternative to the default HTML renderer when higher graphical fidelity is needed in Flutter web apps. - **Use Original Engine Initialization**: This uses original Flutter web engine initialization, which sometimes helps in better loading time in the deployed web app. @@ -152,7 +163,7 @@ When you are ready to deploy, click **Publish.** This will take approximately 2- By default, you will publish to a subdomain based on your project id. These default subdomain addresses do not count toward the subdomain quota, and you can deploy as many projects as you'd like. The URL would look like this: `your-project-id-1234.flutterflow.app` -You can also modify the address by specifying a custom subdomain address, in the **Settings > Web Publishing** tab's **Site URL** field, as long as it's available. You can have up to **2** custom subdomain URLs on the Free plan, up to **20** on any of our Paid plans, and **unlimited** custom subdomain URLs on the Enterprise plan. +You can also modify the address by specifying an available custom subdomain in **Settings > Web Publishing > Site URL**. Limits vary by plan and are shown in FlutterFlow and on the current pricing page. :::info @@ -193,7 +204,7 @@ To add a custom domain: 1. Enter your **Custom Domain URL**. Ensure you only enter the domain name (without www) and extension (e.g.,*mywebapp.com* and not *www.mywebapp.com*). 2. Now, you must set up the DNS. To do so: 1. Visit the website from where you bought the domain. - 2. Open the DNS manager and create the records as per displayed in UI. **Note** that there should not be other A or AAA records after adding this. Here are quick links on how to do this on popular domain-selling websites. 1) [Godaddy](https://in.godaddy.com/help/add-an-a-record-19238) 2) [Namecheap](https://www.namecheap.com/support/knowledgebase/article.aspx/319/2237/how-can-i-set-up-an-a-address-record-for-my-domain/) 3) [Google Domains](https://support.google.com/a/answer/2579934?hl=en). Here's an example of how it looks in Godaddy. + 2. Open the DNS manager and create the exact records displayed in FlutterFlow. Remove only records for the same host that conflict with those instructions; unrelated records can serve email or other subdomains and should not be deleted. DNS changes can take time to propagate. ![custom-domain-listing.avif](../imgs/custom-domain-listing.avif) 3. Click **Connect**. 4. Once the domain is connected, hit the **Publish** button again. @@ -207,7 +218,7 @@ If you are familiar with HTML, you may set any additional headers (e.g., [style] :::warning -These headers are used directly in the `index.html` of your site, so malformed headers may cause unexpected behavior (just as directly editing `index.html` would). +These headers are inserted directly into `index.html`. Malformed or untrusted HTML or JavaScript can break the app, expose user data, weaken Content Security Policy, or enable account compromise. Add only reviewed code from trusted sources, avoid embedding secrets, pin third-party resources where possible, and retest privacy consent and security headers after every change. ::: @@ -224,11 +235,9 @@ You can verify the added custom header by opening the inspect element window (** --- -## Changing Firebase dynamic link - -If you do web deployment and utilize Firebase dynamic links in your app, it's recommended that you update your Firebase Dynamic Links URL scheme. This adjustment is necessary to ensure shared links open correctly on the web. By doing so, your dynamic links will function properly for users across all platforms. +## Replace legacy Firebase Dynamic Links -![update-firebase-dynamic-link.avif](../imgs/update-firebase-dynamic-link.avif) +Firebase Dynamic Links shut down on August 25, 2025. Do not configure it for a new deployment, and do not assume an old Dynamic Links URL will continue routing. Migrate existing links to supported web and app deep links, update associated domains and Android App Links, replace links in campaigns and stored content, and test installed and uninstalled flows before removing the legacy domain. See [Deep and Dynamic Linking](../../ff-concepts/navigation-routing/deep-dynamic-linking.md) for FlutterFlow's current routing options. --- @@ -244,9 +253,8 @@ To enable your subdomain as an authorized domain: height: 0, width: '100%' }}> -