npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@fluid-app/react-widgets

v1.0.12

Published

React components for the Fluid shopping experience with built-in attribution tracking.

Downloads

205

Readme

Fluid React Widgets

React components for the Fluid shopping experience with built-in attribution tracking.

Installation

npm install @fluid-app/react-widgets
# or
yarn add @fluid-app/react-widgets
# or
pnpm add @fluid-app/react-widgets

Quick Start

Here's a complete example to get up and running with the Cart Widget in a React application:

import React from "react";

import { CartWidget, initializeFluid } from "@fluid-app/react-widgets";

// Initialize the Fluid SDK once in your app (typically in your main component or App.js)
function App() {
  React.useEffect(() => {
    // Initialize with your shop ID (server-side attribution)
    initializeFluid({
      fluidShop: "your-shop-id", // Replace with your actual shop ID
    });

    // Or with attribution override
    initializeFluid({
      fluidShop: "your-shop-id",
      attributionOverride: {
        share_guid: "your-affiliate-id",
      },
    });
  }, []);

  return (
    <div className="app">
      <h1>My Awesome Store</h1>

      {/* Add the cart widget to your app */}
      <CartWidget
        position="bottom-right"
        fluidShopDisplayName="My Awesome Store"
      />

      {/* Your other app content */}
      <main>{/* Your products, pages, etc. */}</main>
    </div>
  );
}

export default App;

Customizing Widget Styles

The widgets can be customized to match your brand's color scheme using CSS variables. First, make sure to import the widget styles:

// In your main CSS file or component
import "@fluid-app/react-widgets/dist/styles.css";

Or if you prefer using CSS imports:

@import url("../node_modules/@fluid-app/react-widgets/dist/styles.css");

Then, you can customize the widget's appearance by setting CSS variables:

/* In your CSS file */
:root {
  --company-color: #27522e; /* Replace with your brand color */
  --ff-body: "Your Custom Font", sans-serif; /* Your custom font */
}

Available customization variables:

  • --company-color: Controls primary colors, accents, and highlights
  • --ff-body: Sets the font family used throughout the widgets (falls back to system fonts if not specified)

This will apply your brand's color and typography to various elements of the Fluid widgets like buttons, text, borders, and accents.

Setting Up Attribution

Attribution is built into the Fluid SDK and automatically works with the React widgets using server-side attribution calculation. No client-side configuration is needed:

// For React applications with server-side attribution
import { initializeFluid } from "@fluid-app/react-widgets";

function FluidInitializer() {
  React.useEffect(() => {
    // Basic server-side attribution (recommended)
    initializeFluid({
      fluidShop: "your-shop-id",
    });

    // Or with attribution override for specific use cases
    // You can use any of these attribution data formats:

    // Attribution by email
    initializeFluid({
      fluidShop: "your-shop-id",
      attributionOverride: {
        email: "[email protected]",
      },
    });

    // Attribution by username
    initializeFluid({
      fluidShop: "your-shop-id",
      attributionOverride: {
        username: "influencer-username",
      },
    });

    // Attribution by share GUID
    initializeFluid({
      fluidShop: "your-shop-id",
      attributionOverride: {
        share_guid: "abc123-def456-ghi789",
      },
    });

    // Attribution by Fluid rep ID
    initializeFluid({
      fluidShop: "your-shop-id",
      attributionOverride: {
        fluid_rep_id: 12345,
      },
    });

    // Attribution by external ID
    initializeFluid({
      fluidShop: "your-shop-id",
      attributionOverride: {
        external_id: "external-affiliate-id",
      },
    });
  }, []);

  return null; // This component doesn't render anything
}

// Add <FluidInitializer /> to your main App component

🔄 Migration Note: Client-side attribution patterns are deprecated. Attribution is now handled server-side automatically.

Usage Examples

Basic Cart Widget

import { CartWidget } from "@fluid-app/react-widgets";

function MyComponent() {
  return (
    <div>
      <CartWidget
        position="bottom-right" // Options: top-left, top-right, bottom-left, bottom-right
        size={60} // Size in pixels
        zIndex={50} // Z-index for the widget
        xMargin={40} // Horizontal margin from edge in pixels
        yMargin={98} // Vertical margin from edge in pixels
        fluidShopDisplayName="My Store" // Name displayed in cart
      />
    </div>
  );
}

Custom Cart Button with Hidden Widget

import { CartWidget, openCart } from "@fluid-app/react-widgets";

function CustomCartButton() {
  return (
    <div>
      {/* Hide the default cart widget button */}
      <CartWidget hideWidget={true} />

      {/* Use your own custom button to control the cart */}
      <button className="custom-cart-button" onClick={openCart}>
        My Custom Cart Button
        <span className="cart-count">3</span>
      </button>
    </div>
  );
}

Controlling the Cart Programmatically

import { closeCart, openCart, toggleCart } from "@fluid-app/react-widgets";

function ProductCard({ product }) {
  const handleAddToCart = async () => {
    // Add the product to cart
    // ...your add to cart logic

    // Then open the cart drawer
    openCart();
  };

  return (
    <div className="product-card">
      <h3>{product.name}</h3>
      <p>${product.price}</p>
      <button onClick={handleAddToCart}>Add to Cart</button>

      {/* Additional cart control buttons if needed */}
      <div className="cart-controls">
        <button onClick={openCart}>Open Cart</button>
        <button onClick={closeCart}>Close Cart</button>
        <button onClick={toggleCart}>Toggle Cart</button>
      </div>
    </div>
  );
}

Accessing Cart Count

You can access the current cart count using the getCartItemCount function from the @fluid-app/fluid package:

import { useEffect, useState } from "react";

import { getCartItemCount, getLocalCart } from "@fluid-app/fluid";

function CartIndicator() {
  const [itemCount, setItemCount] = useState(0);

  useEffect(() => {
    // Initial cart count
    setItemCount(getCartItemCount());

    // Function to update the cart count
    const updateCartCount = () => {
      setItemCount(getCartItemCount());
    };

    // Listen for cart events
    window.addEventListener("ADD_TO_CART", updateCartCount);
    window.addEventListener("REMOVE_CART_ITEM", updateCartCount);
    window.addEventListener("UPDATE_CART_ITEM", updateCartCount);
    window.addEventListener("CREATE_CART", updateCartCount);

    return () => {
      // Clean up event listeners
      window.removeEventListener("ADD_TO_CART", updateCartCount);
      window.removeEventListener("REMOVE_CART_ITEM", updateCartCount);
      window.removeEventListener("UPDATE_CART_ITEM", updateCartCount);
      window.removeEventListener("CREATE_CART", updateCartCount);
    };
  }, []);

  return (
    <div className="cart-indicator">
      <i className="shopping-cart-icon" />
      <span className="cart-count">{itemCount}</span>
    </div>
  );
}

HTML Cart Count Element

Alternatively, you can use an HTML element with the ID fluid-cart-count that will be automatically updated by the SDK:

function CartIndicator() {
  return (
    <div className="cart-indicator">
      <i className="shopping-cart-icon" />
      <span id="fluid-cart-count">0</span>
    </div>
  );
}

Cart Functions

The cart widget provides three functions to control it:

import { closeCart, openCart, toggleCart } from "@fluid-app/react-widgets";

// Open the cart drawer
openCart();

// Close the cart drawer
closeCart();

// Toggle the cart drawer (open if closed, close if open)
toggleCart();

Next.js App Router Integration

For Next.js with App Router, create a client component to initialize the SDK:

// app/components/FluidInitializer.tsx
"use client";

import { useEffect, useState } from "react";

import { initializeFluid } from "@fluid-app/react-widgets";

export default function FluidInitializer() {
  const [isInitialized, setIsInitialized] = useState(false);

  useEffect(() => {
    if (isInitialized) return;

    try {
      initializeFluid({
        fluidShop: "your-shop-id",
      });

      setIsInitialized(true);
    } catch (error) {
      console.error("Error initializing Fluid SDK:", error);
    }
  }, [isInitialized]);

  return null;
}

// Then in your layout.tsx file:
// import FluidInitializer from './components/FluidInitializer';
// Add <FluidInitializer /> to your RootLayout component

CartWidget Props

| Prop | Type | Default | Description | | -------------------- | ------------------------------------------------------------ | -------------- | ------------------------------------------------------------------------------------- | | position | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'bottom-right' | The position of the cart widget | | size | number | 60 | The size of the cart widget in pixels | | zIndex | number | 50 | The z-index of the cart widget | | xMargin | number | 40 | The horizontal margin from the edge of the screen in pixels | | yMargin | number | 98 | The vertical margin from the edge of the screen in pixels | | onCheckout | () => void | - | Callback function when the checkout button is clicked | | fluidShopDisplayName | string | 'My Store' | The display name of the shop shown in the cart header | | hideWidget | boolean | false | When true, hides the cart widget button but still allows the cart sheet functionality |

Troubleshooting

  1. Attribution not tracking: Attribution is now handled server-side automatically. Ensure your Fluid shop is properly configured.

  2. Cart widget not appearing: Verify that the Fluid SDK is initialized before rendering the cart widget.

  3. Initialization issues: Check the console for any errors during initialization. Ensure you're calling initializeFluid with the correct parameters.