> ## Documentation Index
> Fetch the complete documentation index at: https://docs-staging-quickstart-revamp.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> This guide demonstrates how to integrate Auth0 with an Ionic (React) & Capacitor application using the Auth0 React SDK.

# Add login to your Ionic React with Capacitor app

export const LoggedInForm = ({sampleApp}) => {
  const LS_APPS_KEY = "auth_demo_apps";
  const LS_APP_CFG_KEY = "auth_demo_app_cfg";
  const CHANNEL = "auth_flows_sync_v1";
  const mkChannel = () => new BroadcastChannel(CHANNEL);
  function uid() {
    return Math.random().toString(36).slice(2) + Date.now().toString(36);
  }
  function loadApps() {
    const raw = localStorage.getItem(LS_APPS_KEY);
    if (raw) return JSON.parse(raw);
    const seeded = [{
      id: "mz9iNEIo2PHu7oeh8QRt19ndTyyCIgai",
      name: "Default App"
    }];
    localStorage.setItem(LS_APPS_KEY, JSON.stringify(seeded));
    return seeded;
  }
  function saveApps(apps) {
    localStorage.setItem(LS_APPS_KEY, JSON.stringify(apps));
  }
  function loadCfg() {
    const raw = localStorage.getItem(LS_APP_CFG_KEY);
    return raw ? JSON.parse(raw) : {};
  }
  function saveCfg(cfg) {
    localStorage.setItem(LS_APP_CFG_KEY, JSON.stringify(cfg));
  }
  const RightChevron = ({className = "w-5 h-5", ...props}) => <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke="currentColor" fill="none" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className={className} {...props}>
      <polyline points="9 18 15 12 9 6" />
    </svg>;
  const LightningIcon = () => <svg width="24" height="24" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
      <path fillRule="evenodd" clipRule="evenodd" className="fill-[#3F59E4] dark:fill-[#99A7F1]" d="M24.971 30.152H7.088c-1.786 0-2.745-2.103-1.574-3.453l19.07-21.988c1.33-1.532 3.835-.4 3.569 1.607L24.97 30.152z" />
      <path fillRule="evenodd" clipRule="evenodd" className="fill-[#3F59E4] dark:fill-[#99A7F1]" d="M23.201 17.885h17.885c1.787 0 2.746 2.102 1.575 3.453l-19.073 21.99c-1.33 1.532-3.835.4-3.568-1.607L23.2 17.885z" />
    </svg>;
  const LayersIcon = () => <svg width="24" height="24" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
      <path className="fill-[#3F59E4] dark:fill-[#99A7F1]" d="M34.54 29.135l6.373 3.183c1.566.782 1.566 3.017 0 3.8l-14.815 7.396a4.623 4.623 0 01-4.125 0L7.174 36.12c-1.565-.782-1.565-3.017 0-3.798l6.532-3.214" />
      <path className="fill-[#AAB6F3] dark:fill-[#3449BA]" d="M34.54 18.86l6.373 3.183c1.566.782 1.566 3.016 0 3.8L26.098 33.24a4.623 4.623 0 01-4.125 0L7.174 25.843c-1.565-.781-1.565-3.016 0-3.798l6.33-3.164" />
      <path className="fill-[#CFD6F8] dark:fill-[#22307C]" d="M21.94 23.058L7.306 15.745c-1.62-.81-1.62-3.123 0-3.932l14.631-7.319a4.693 4.693 0 014.194 0l14.648 7.319c1.622.81 1.62 3.124 0 3.932L26.13 23.058c-1.321.66-2.873.66-4.191 0z" />
    </svg>;
  const GithubIcon = () => <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="w-5 h-5">
      <path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"></path>
    </svg>;
  function IconTile({children}) {
    return <div className="
          shrink-0 grid place-items-center w-10 h-10 rounded-lg
          bg-indigo-50 ring-1 ring-indigo-200/60
          dark:bg-indigo-950/40 dark:ring-white/10
        ">
        {children}
      </div>;
  }
  function Card({className = "", children}) {
    return <div className={`rounded-2xl shadow-sm ring-1 ring-zinc-200 dark:ring-zinc-800 ${className}`}>{children}</div>;
  }
  function Button({variant = "primary", type = "button", onClick, children}) {
    const base = "inline-flex items-center justify-center gap-2 h-10 px-4 rounded-xl font-medium transition";
    let styles = "";
    if (variant === "primary") {
      styles = "mint-bg-indigo-600 text-white hover:mint-bg-indigo-700";
    } else if (variant === "outline") {
      styles = "border border-zinc-300 dark:border-zinc-700 mint-bg-transparent hover:mint-bg-zinc-50 dark:hover:mint-bg-zinc-800";
    } else if (variant === "ghost") {
      styles = "hover:mint-bg-zinc-100 dark:hover:mint-bg-zinc-800";
    }
    return <button type={type} onClick={onClick} className={`${base} ${styles}`}>
        {children}
      </button>;
  }
  function Input({id, label, value, onChange, placeholder, name}) {
    return <label className="block space-y-1">
        <span className="text-sm text-zinc-700 dark:text-zinc-300">{label}</span>
        <input id={id} name={name} className="w-full h-11 px-3 rounded-xl border border-zinc-300 dark:border-zinc-700 bg-white dark:bg-zinc-900 text-zinc-900 dark:text-zinc-100 focus:outline-none focus:ring-2 focus:ring-indigo-500" placeholder={placeholder} value={value} onChange={e => onChange(e.target.value)} />
      </label>;
  }
  function Select({label, value, onChange, options}) {
    return <label className="block space-y-1 max-w-[300px]">
        <span className="text-sm text-zinc-700 dark:text-zinc-300">{label}</span>
        <div className="relative">
          <select className="w-full h-11 appearance-none px-3 pr-9 rounded-xl border border-zinc-300 dark:border-zinc-700 bg-white dark:bg-zinc-900 text-zinc-900 dark:text-zinc-100 focus:outline-none focus:ring-2 focus:ring-indigo-500" value={value} onChange={e => onChange(e.target.value)}>
            <optgroup label="Generic Applications">
              {options.map(o => <option key={o.id} value={o.id}>
                  {o.name}
                </option>)}
            </optgroup>
          </select>
          <svg className="pointer-events-none absolute right-3 top-1/2 -translate-y-1/2 w-5 h-5 text-zinc-500" viewBox="0 0 24 24">
            <path d="M7 10l5 5 5-5z" fill="currentColor" />
          </svg>
        </div>
      </label>;
  }
  function Toast({open, onClose, children}) {
    useEffect(() => {
      if (!open) return;
      const t = setTimeout(onClose, 2200);
      return () => clearTimeout(t);
    }, [open, onClose]);
    return <div className={`fixed right-4 top-4 z-50 transition ${open ? "opacity-100 translate-y-0" : "opacity-0 -translate-y-2 pointer-events-none"}`}>
        <div className="flex items-center gap-2 rounded-xl shadow ring-1 ring-emerald-200 bg-white dark:bg-zinc-900 px-4 py-2">
          <span className="w-1.5 h-8 rounded-l bg-emerald-500" />
          <svg className="w-5 h-5 text-emerald-600" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
            <path d="M20 6L9 17l-5-5" />
          </svg>
          <span className="text-sm text-zinc-900 dark:text-zinc-100">{children}</span>
        </div>
      </div>;
  }
  function Flows() {
    const [route, setRoute] = useState("menu");
    const [apps, setApps] = useState(loadApps());
    const [cfg, setCfg] = useState(loadCfg());
    const [selected, setSelected] = useState(apps[0]?.id || "");
    const [toast, setToast] = useState(false);
    const [bc] = useState(() => mkChannel());
    useEffect(() => {
      if (!apps.find(a => a.id === selected)) {
        setSelected(apps[0]?.id || "");
      }
    }, [apps, selected]);
    useEffect(() => {
      const onMsg = e => {
        const {type, payload} = e.data || ({});
        switch (type) {
          case "NAV":
            setRoute(payload.route);
            break;
          case "SELECT":
            setSelected(payload.appId);
            break;
          case "APPS_UPDATED":
            setApps(loadApps());
            break;
          case "CFG_UPDATED":
            setCfg(loadCfg());
            setToast(true);
            break;
          default:
            break;
        }
      };
      bc.addEventListener("message", onMsg);
      return () => bc.removeEventListener("message", onMsg);
    }, [bc]);
    const nav = nextRoute => {
      setRoute(nextRoute);
      bc.postMessage({
        type: "NAV",
        payload: {
          route: nextRoute
        }
      });
    };
    const selectApp = appId => {
      setSelected(appId);
      bc.postMessage({
        type: "SELECT",
        payload: {
          appId
        }
      });
    };
    const onCreate = name => {
      const id = uid();
      const next = [...apps, {
        id,
        name: name || "Untitled"
      }];
      setApps(next);
      saveApps(next);
      bc.postMessage({
        type: "APPS_UPDATED"
      });
      selectApp(id);
      nav("integrate");
    };
    const onSaveCfg = (appId, data) => {
      const next = {
        ...cfg,
        [appId]: data
      };
      setCfg(next);
      saveCfg(next);
      setToast(true);
      bc.postMessage({
        type: "CFG_UPDATED"
      });
    };
    return <div>
        {route === "menu" && <Menu onCreate={() => nav("create")} onIntegrate={() => nav("integrate")} />}

        {route === "create" && <CreateForm onCancel={() => nav("menu")} onSave={onCreate} />}

        {route === "integrate" && <IntegrateForm apps={apps} selected={selected} onSelect={selectApp} saved={cfg[selected]} onSave={data => onSaveCfg(selected, data)} onCancel={() => nav("menu")} />}

        <Toast open={toast} onClose={() => setToast(false)}>
          Successfully saved your changes.
        </Toast>
      </div>;
  }
  function Menu({onCreate, onIntegrate}) {
    return <ul className="space-y-4 list-none login_list">
        <li className="list-none !px-0">
          <button onClick={onCreate} className="w-full text-left">
            <Card className="p-5 hover:shadow-md transition">
              <div className="flex items-center justify-between">
                <div className="flex items-center gap-4">
                  <IconTile>
                    <LightningIcon />
                  </IconTile>
                  <h2 className="text-lg">Create a new application</h2>
                </div>
                <RightChevron className="w-4 h-4 text-zinc-500" />
              </div>
            </Card>
          </button>
        </li>
        <li className="list-none !px-0">
          <button onClick={onIntegrate} className="w-full text-left">
            <Card className="p-5 hover:shadow-md transition">
              <div className="flex items-center justify-between">
                <div className="flex items-center gap-4">
                  <IconTile>
                    <LayersIcon />
                  </IconTile>
                  <h2 className="text-lg">Integrate with an existing application</h2>
                </div>
                <RightChevron className="w-4 h-4 text-zinc-500" />
              </div>
            </Card>
          </button>
        </li>
        <li className="list-none !px-0">
          <a className="no_external_icon block" href={sampleApp ? sampleApp : "/"} target="_blank" rel="noreferrer">
            <Card className="p-5 hover:shadow-md transition">
              <div className="flex items-center justify-between">
                <div className="flex items-center gap-4">
                  <IconTile>
                    <GithubIcon />
                  </IconTile>
                  <h2 className="text-lg">View a sample application</h2>
                </div>
                <RightChevron className="w-4 h-4 text-zinc-500" />
              </div>
            </Card>
          </a>
        </li>
      </ul>;
  }
  function CreateForm({onSave, onCancel}) {
    const [name, setName] = useState("");
    return <div className="space-y-6">
        <Input id="app-name" label="Application Name" placeholder="My App" value={name} onChange={setName} />
        <p className="text-sm text-zinc-500">You can change this later in the application settings.</p>
        <div className="flex gap-3">
          <Button onClick={() => onSave(name)}>Save</Button>
          <Button variant="outline" onClick={onCancel}>
            Cancel
          </Button>
        </div>
      </div>;
  }
  function IntegrateForm({apps, selected, onSelect, saved, onSave, onCancel}) {
    const [callbacks, setCallbacks] = useState(saved?.callbacks ?? "");
    const [logouts, setLogouts] = useState(saved?.logouts ?? "");
    const [origins, setOrigins] = useState(saved?.origins ?? "");
    useEffect(() => {
      setCallbacks(loadCfg()[selected]?.callbacks ?? "");
      setLogouts(loadCfg()[selected]?.logouts ?? "");
      setOrigins(loadCfg()[selected]?.origins ?? "");
    }, [selected]);
    return <div className="space-y-6">
        <div>
          <span className="block text-sm text-zinc-600 dark:text-zinc-300 mb-1">Select your Application</span>
          <Select label="" value={selected} onChange={onSelect} options={apps} />
        </div>

        <form className="space-y-4" onSubmit={e => {
      e.preventDefault();
      onSave({
        callbacks,
        logouts,
        origins
      });
    }}>
          <Input id="callbacks" name="callbacks" label="Callback URLs" placeholder="http://localhost:3000" value={callbacks} onChange={setCallbacks} />
          <Input id="logout" name="allowed_logout_urls" label="Logout URLs" placeholder="http://localhost:3000" value={logouts} onChange={setLogouts} />
          <Input id="origins" name="web_origins" label="Allowed Web Origins" placeholder="http://localhost:3000" value={origins} onChange={setOrigins} />

          <div className="flex gap-3 pt-2">
            <Button type="submit">Save</Button>
            <Button variant="outline" type="button" onClick={onCancel}>
              Cancel
            </Button>
          </div>
        </form>
      </div>;
  }
  return <div className="w-full mx-auto py-8">
      <Flows />
    </div>;
};

export const SignUpForm = () => {
  return <div className="flex flex-col gap-2 items-center h-full">
      <img noZoom src="/docs/img/quickstarts/action_hero_dashboard.svg" alt="Sign up for an Auth0 account" style={{
    width: "250px",
    height: "250px"
  }} />
      <span className="text-center" style={{
    width: "400px"
  }}>
        Sign up for an{" "}
        <a href="https://auth0.com/signup" target="_blank" rel="noopener noreferrer">
          Auth0 account
        </a>{" "}
        or{" "}
        <span className="font-semibold text-primary cursor-pointer" onClick={() => console.log("log in")}>
          log in
        </span>{" "}
        to your existing account to integrate directly with your own tenant.
      </span>
      <button onClick={() => console.log("sign up")} className="bg-primary dark:bg-primary-light text-white dark:text-black px-4 py-2 rounded-md mt-4 font-medium" style={{
    width: "140px"
  }}>
        Sign up
      </button>
    </div>;
};

export const SideMenuSectionItem = ({id, children}) => {
  return <div id={`side-menu-item-${id}`} className="recipe-side-menu-item flex flex-col w-full h-full">
      {children}
    </div>;
};

export const SideMenu = ({sections, children}) => {
  const [visibleSection, setVisibleSection] = useState(sections[0]?.id ?? null);
  const checkVisibility = () => {
    let currentVisible = null;
    const viewportHeight = window.innerHeight;
    const scrollY = window.scrollY;
    sections.forEach(({id}) => {
      const section = document.getElementById(id);
      if (section) {
        const rect = section.getBoundingClientRect();
        const sectionTop = rect.top + scrollY;
        const sectionBottom = sectionTop + rect.height;
        const multiplier = viewportHeight > 1600 ? 0.34 : 0.22;
        if (scrollY + viewportHeight * multiplier >= sectionTop && scrollY <= sectionBottom) {
          currentVisible = id;
        }
      }
    });
    if (currentVisible && currentVisible !== visibleSection) {
      setVisibleSection(currentVisible);
    }
  };
  useEffect(() => {
    const throttledCheck = () => {
      setTimeout(checkVisibility, 100);
    };
    checkVisibility();
    window.addEventListener("scroll", throttledCheck);
    return () => {
      window.removeEventListener("scroll", throttledCheck);
    };
  }, [sections, visibleSection]);
  useEffect(() => {
    sections.forEach(({id}) => {
      const section = document.getElementById(id);
      const sideMenuItem = document.getElementById(`side-menu-item-${id}`);
      if (section) {
        if (id === visibleSection) {
          section.classList.add("active-section");
        } else {
          section.classList.remove("active-section");
        }
      }
      if (sideMenuItem) {
        if (id === visibleSection) {
          sideMenuItem.classList.add("active-side-menu-item");
        } else {
          sideMenuItem.classList.remove("active-side-menu-item");
        }
      }
    });
  }, [visibleSection, sections]);
  return <div className="recipe-side-menu sticky px-2 py-1" style={{
    height: "calc(100vh - 7rem)",
    top: "7rem",
    scrollMarginTop: "var(--scroll-mt)"
  }}>
      {children.map(child => {
    if (child.props.id === visibleSection) {
      return child;
    }
    return null;
  })}
    </div>;
};

export const Section = ({id, title, stepNumber, children, isSingleColumn = false}) => {
  return <div id={id} className={`recipe-section flex flex-col transition-opacity duration-200`}>
      {}
      <Step title={title} stepNumber={stepNumber} titleSize="h3">
        {children}
      </Step>
    </div>;
};

export const Content = ({title, children}) => {
  return <div className="recipe-content flex flex-col">
      {title && <h1 className="text-3xl">{title}</h1>}
      {children}
    </div>;
};

export const Recipe = ({children, isSingleColumn = false}) => {
  return <div className={`pl-4 recipe-container mx-auto grid grid-cols-1 gap-10 relative ${isSingleColumn ? "md:grid-cols-1" : "md:grid-cols-2"}`}>
      {children}
    </div>;
};

export const sections = [{
  id: "getting-started",
  title: "Getting started"
}, {
  id: "configure-auth0",
  title: "Configure Auth0"
}, {
  id: "install-the-auth0-react-sdk",
  title: "Install the Auth0 React SDK"
}, {
  id: "configure-the-auth0provider-component",
  title: "Configure the Auth0Provider component"
}, {
  id: "add-login-to-your-application",
  title: "Add login to your application"
}, {
  id: "handle-the-login-callback",
  title: "Handle the login callback"
}, {
  id: "add-logout-to-your-application",
  title: "Add logout to your application"
}, {
  id: "show-the-user-profile",
  title: "Show the user profile"
}];

<Recipe>
  <Content>
    Auth0 allows you to quickly add authentication and gain access to user profile information in your application.
    This guide demonstrates how to integrate Auth0 with an Ionic (React) & Capacitor application using the [Auth0 React SDK](https://github.com/auth0/auth0-react).

    <Section id={sections[0].id} title={sections[0].title} stepNumber="1">
      This quickstart assumes you already have an [Ionic](https://ionicframework.com/) application up and running with [Capacitor](https://capacitorjs.com/). If not, check out the [Using
      Capacitor with Ionic Framework guide](https://capacitorjs.com/docs/getting-started/with-ionic) to get started with a simple app, or clone [our sample
      apps](https://github.com/auth0-samples/auth0-ionic-samples).

      You should also be familiar with the [Capacitor development workflow](https://capacitorjs.com/docs/basics/workflow).
    </Section>

    <Section id={sections[1].id} title={sections[1].title} stepNumber="2">
      To use Auth0 services, you need to have an application set up in the Auth0 Dashboard. The Auth0 application is
      where you will configure how you want authentication to work for your project.

      <Info>
        Throughout this article, `YOUR_PACKAGE_ID` is your application's package ID. This can be
        found and configured in the `appId` field in your `capacitor.config.ts` file. See
        [Capacitor's Config schema](https://capacitorjs.com/docs/config#schema) for more info.
      </Info>

      ### Configure an application

      Use the interactive selector to create a new Auth0 application or select an existing application that represents
      the project you want to integrate with. Every application in Auth0 is assigned an alphanumeric, unique client ID
      that your application code will use to call Auth0 APIs through the SDK.

      Any settings you configure using this quickstart will automatically update for your application in the [Dashboard](https://manage.auth0.com/#/), which is where you
      can manage your applications in the future.

      If you would rather explore a complete configuration, you can view a sample application instead.

      ### Configure Callback URLs

      A callback URL is a URL in your application that you would like Auth0 to redirect users to after they have
      authenticated. If not set, users will not be returned to your application after they log in.

      <Info>
        If you are following along with our sample project, set this to:

        `YOUR_PACKAGE_ID://{yourTenant}.auth0.com/capacitor/YOUR_PACKAGE_ID/callback`
      </Info>

      ### Configure Logout URLs

      A logout URL is a URL in your application that you would like Auth0 to redirect users to after they have logged
      out. If not set, users will not be able to log out from your application and will receive an error.

      <Info>
        If you are following along with our sample project, set this to:

        `YOUR_PACKAGE_ID://{yourTenant}.auth0.com/capacitor/YOUR_PACKAGE_ID/callback`.
      </Info>

      ### Configure Allowed Origins

      To be able to make requests from your native application to Auth0, set the following **Allowed Origins** in
      your [Application Settings](https://manage.auth0.com/dashboard/#/applications/\{yourClientId}/settings).

      <Info>
        If you are following along with our sample project, set this to
        `capacitor://localhost, http://localhost` for iOS and Android respectively.
      </Info>

      Lastly, be sure that the **Application Type** for your application is set to **Native** in the [Application Settings](https://manage.auth0.com/dashboard/#/applications/\{yourClientId}/settings).
    </Section>

    <Section id={sections[2].id} title={sections[2].title} stepNumber="3">
      Run the following command within your project directory to install the Auth0 React SDK:

      ```bash
      npm install @auth0/auth0-react
      ```

      The SDK exposes methods and variables that help you integrate Auth0 with your React application idiomatically
      using [React
      Hooks](https://reactjs.org/docs/hooks-overview.html) or [Higher-Order Components](https://reactjs.org/docs/higher-order-components.html).

      ### Install Capacitor plugins

      This quickstart and sample make use of some of Capacitor's official plugins. Install these into your app using
      the following command:

      ```bash
      npm install @capacitor/browser @capacitor/app
      ```

      * [@capacitor/browser](https://capacitorjs.com/docs/apis/browser): Allows you to interact with the device's
        system browser and is used to open the URL to Auth0's authorization endpoint.
      * [@capacitor/app](https://capacitorjs.com/docs/apis/app): Allows you to subscribe to high-level app events,
        useful for handling callbacks from Auth0.

      <Info>
        Capacitor's Browser plugin on iOS uses [SFSafariViewController](https://developer.apple.com/documentation/safariservices/sfsafariviewcontroller), which on iOS 11+ does not share
        cookies with Safari on the device. This means that SSO will not work on those devices. If you need
        SSO, please instead use a compatible plugin that uses [ASWebAuthenticationSession](https://developer.apple.com/documentation/authenticationservices/aswebauthenticationsession).
      </Info>
    </Section>

    <Section id={sections[3].id} title={sections[3].title} stepNumber="4">
      Under the hood, the Auth0 React SDK uses [React Context](https://reactjs.org/docs/context.html) to manage the authentication state of your users. One way to
      integrate Auth0 with your React app is to wrap your root component with an `Auth0Provider` you can
      import from the SDK.

      The `Auth0Provider` component takes the following props:

      * `domain`: The `domain`value present under the \*\*Settings \*\*of the application you
        created in your Auth0 Dashboard, or your custom domain if using Auth0's Custom Domains feature.
      * `clientId`: The Client ID value present under the \*\*Settings \*\*of the application you created
        in your Auth0 Dashboard.
      * `useRefreshTokens`: To use auth0-react with Ionic on Android and iOS, it's required to enable
        refresh tokens.
      * `useRefreshTokensFallback`: To use auth0-react with Ionic on Android and iOS, it's required to
        disable the iframe fallback.
      * `authorizationParams.redirect_uri`: The URL to where you'd like to redirect your users after they
        authenticate with Auth0.

      <Info>
        To persist authentication after closing and reopening the application, you may want to set
        `cacheLocation` to `localstorage` when configuring the SDK, but please be aware of
        [the risks of
        storing tokens in localstorage](/docs/libraries/auth0-single-page-app-sdk#change-storage-options). Also, localstorage should be treated as **transient** in
        Capacitor app as the data might be recovered unexpectedly in certain circumstances. Please read the [guidance on storage in the Capacitor docs](https://capacitorjs.com/docs/guides/storage#why-cant-i-just-use-localstorage-or-indexeddb).

        Additionally, the SDK has the ability to [use a custom cache implementation](https://github.com/auth0/auth0-spa-js/blob/master/EXAMPLES.md#creating-a-custom-cache) to store tokens, if
        you have a requirement to use a more secure and persistent storage mechanism.

        **Note** that we recommend **against** using [Capacitor's Storage plugin](https://capacitorjs.com/docs/apis/storage) to store tokens, as this is
        backed by [UserDefaults](https://developer.apple.com/documentation/foundation/userdefaults) and [SharedPreferences](https://developer.android.com/reference/android/content/SharedPreferences) on iOS and Android respectively. Data stored using
        these APIs is not encrypted, not secure, and could also be synced to the cloud.
      </Info>

      <Note>
        ##### Checkpoint

        Add the `Auth0Provider` component in a way that wraps your `App` component, then
        run your application to verify that the SDK is initializing correctly and your application is not throwing
        any errors related to Auth0.
      </Note>
    </Section>

    <Section id={sections[4].id} title={sections[4].title} stepNumber="5">
      In a Capacitor application, the [Capacitor's Browser plugin](https://capacitorjs.com/docs/apis/browser) performs a redirect to the Auth0 [Universal Login Page](https://auth0.com/universal-login). Set the `openUrl`
      parameter on the `loginWithRedirect` function to use `Browser.open` so that the URL is
      opened using the device's system browser component ([SFSafariViewController](https://developer.apple.com/documentation/safariservices/sfsafariviewcontroller) on iOS, and [Chrome
      Custom Tabs](https://developer.chrome.com/docs/android/custom-tabs) on Android).

      <Info>
        By default, the SDK's `loginWithRedirect` method uses `window.location.href` to
        navigate to the login page in the default browser application on the user's device rather than the
        system browser component appropriate for the platform. The user would leave your application to
        authenticate and could make for a suboptimal user experience.
      </Info>

      <Note>
        ##### Checkpoint

        The `loginWithRedirect` function tells the SDK to initiate the login flow, using the
        `Browser.open` function to open the login URL with the platform's system browser component by
        setting the `openUrl` parameter. This provides a way for your user to log in to your
        application. Users redirect to the login page at Auth0 and do not receive any errors.
      </Note>
    </Section>

    <Section id={sections[5].id} title={sections[5].title} stepNumber="6">
      Once users logs in with the Universal Login Page, they redirect back to your app via a URL with a custom URL
      scheme. The `appUrlOpen` event must be handled within your app. You can call the
      `handleRedirectCallback` method from the Auth0 SDK to initialize the authentication state.

      You can only use this method on a redirect from Auth0. To verify success, check for the presence of the
      `code` and `state` parameters in the URL.

      The `Browser.close()` method should close the browser when this event is raised.

      <Info>
        This article assumes you will be using Custom URL Schemes to handle the callback within your
        application. To do this, register your `YOUR_PACKAGE_ID` as a URL scheme for your chosen
        platform. To learn more, read [Defining a Custom URL Scheme](https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app) for iOS, or [Create Deep Links to App Content](https://developer.android.com/training/app-links/deep-linking) for Android.
      </Info>

      <Note>
        ##### Checkpoint

        Add the `appUrlOpen` to your application's `App` component and log in. The browser
        window should close once the user authenticates and logs in to your app.
      </Note>
    </Section>

    <Section id={sections[6].id} title={sections[6].title} stepNumber="7">
      Now that users can log in, you need to configure [a way to log out](https://auth0.com/docs/logout/guides/logout-auth0). Users must redirect to the Auth0 logout endpoint in the browser to clear
      their browser session. Again, Capacitor's Browser plugin should perform this redirect so that the user does not
      leave your app and receive a suboptimal experience.

      To achieve this with Ionic and Capacitor in conjunction with the Auth0 SDK:

      * Construct the URL for your app Auth0 should use to redirect to after logout. This is a URL that uses your
        registered custom scheme and Auth0 domain. Add it to your \*\*Allowed Logout URLs \*\*configuration in the
        Auth0 Dashboard
      * Logout from the SDK by calling `logout`, and pass your redirect URL back as the
        `logoutParams.returnTo` parameter.
      * Set the `openUrl` parameter to a callback that uses the Capacitor browser plugin to open the URL
        using `Browser.open`.

      <Info>
        Similar to the login step, if you do not set `openUrl` when calling `logout`, the
        SDK redirects the user to the logout URL using the default browser application on the device, which
        provides a suboptimal user experience.
      </Info>

      <Note>
        ##### Checkpoint

        Provide a way for your users to log out of your application. Verify that you redirect to Auth0 and then
        to the address you specified in the `returnTo` parameter. Check that you are no longer logged
        in to your application.
      </Note>
    </Section>

    <Section id={sections[7].id} title={sections[7].title} stepNumber="8">
      The Auth0 React SDK retrieves the user's profile
      associated with logged-in users in whatever component you need, such as their name or profile picture, to
      personalize the user interface. The profile information is available through the `user` property
      exposed by the `useAuth0()` hook.

      Initializing the SDK is asynchronous, and you should guard the user profile by checking the
      `isLoading` and `user` properties. Once `isLoading` is `false` and
      `user` has a value, the user profile can be used.

      <Note>
        ##### Checkpoint

        Provide a way for your users to see their user profile details within the app and verify you are able to
        retrieve and see your profile information on screen once you have logged in.
      </Note>
    </Section>

    ## Next Steps

    Excellent work! If you made it this far, you should now have login, logout, and user profile information running in your application.

    This concludes our quickstart tutorial, but there is so much more to explore. To learn more about what you can do with Auth0, check out:

    * [Auth0 Dashboard](https://manage.auth0.com/dashboard/us/dev-gja8kxz4ndtex3rq) - Learn how to configure and manage your Auth0 tenant and applications
    * [Auth0 Marketplace](https://marketplace.auth0.com/) - Discover integrations you can enable to extend Auth0’s functionality
  </Content>

  <SideMenu sections={sections}>
    <SideMenuSectionItem id={sections[0].id}>
      <SignUpForm />
    </SideMenuSectionItem>

    <SideMenuSectionItem id={sections[1].id}>
      <SignUpForm />
    </SideMenuSectionItem>

    <SideMenuSectionItem id={sections[2].id}>
      <SignUpForm />
    </SideMenuSectionItem>

    <SideMenuSectionItem id={sections[3].id}>
      <CodeGroup>
        ```tsx index.tsx lines 
        import React from 'react';
        import { createRoot } from 'react-dom/client';
        import { Auth0Provider } from '@auth0/auth0-react';
        import App from './App';

        const root = createRoot(document.getElementById('root'));

        root.render(
          <Auth0Provider
            domain="dev-gja8kxz4ndtex3rq.us.auth0.com"
            clientId="mz9iNEIo2PHu7oeh8QRt19ndTyyCIgai"
            useRefreshTokens={true}
            useRefreshTokensFallback={false}
            authorizationParams={{
              redirect_uri: "YOUR_PACKAGE_ID://dev-gja8kxz4ndtex3rq.us.auth0.com/capacitor/YOUR_PACKAGE_ID/callback"
            }}
          >
            <App />
          </Auth0Provider>
        );
        ```

        ```tsx login-button.tsx lines 
        import { useAuth0 } from '@auth0/auth0-react';
        import { Browser } from '@capacitor/browser';
        import { IonButton } from '@ionic/react';

        const LoginButton: React.FC = () => {
          const { loginWithRedirect } = useAuth0();

          const login = async () => {
            await loginWithRedirect({
              async openUrl(url) {
                 // Redirect using Capacitor's Browser plugin
                await Browser.open({
                  url,
                  windowName: "_self"
                });
              }
            });
          };

          return <IonButton onClick={login}>Log in</IonButton>;
        };

        export default LoginButton;
        ```

        ```tsx logout-button.tsx lines 
        import { useAuth0 } from '@auth0/auth0-react';
        import { Browser } from '@capacitor/browser';
        import { IonButton } from '@ionic/react';

        // This should reflect the URL added earlier to your "Allowed Logout URLs" setting
        // in the Auth0 dashboard.
        const logoutUri = 'YOUR_PACKAGE_ID://dev-gja8kxz4ndtex3rq.us.auth0.com/capacitor/YOUR_PACKAGE_ID/callback';

        const LogoutButton: React.FC = () => {
          const { logout } = useAuth0();

          const doLogout = async () => {
            await logout({
              logoutParams: {
                returnTo: logoutUri
              },
              async openUrl(url) {
                 // Redirect using Capacitor's Browser plugin
                await Browser.open({
                  url,
                  windowName: "_self"
                });
              }
            });
          };

          return <IonButton onClick={doLogout}>Log out</IonButton>;
        };

        export default LogoutButton;
        ```

        ```tsx app.tsx lines 
        // Import Capacitor's app and browser plugins, giving us access to `addListener` and `appUrlOpen`,
        // as well as the bits needed for Auth0 and React
        import { App as CapApp } from '@capacitor/app';
        import { Browser } from '@capacitor/browser';
        import { useEffect } from 'react';
        import { useAuth0 } from '@auth0/auth0-react';

        // ...

        const App: React.FC = () => {
          // Get the callback handler from the Auth0 React hook
          const { handleRedirectCallback } = useAuth0();

          useEffect(() => {
            // Handle the 'appUrlOpen' event and call `handleRedirectCallback`
            CapApp.addListener('appUrlOpen', async ({ url }) => {
              if (url.includes('state') && (url.includes('code') || url.includes('error'))) {
                await handleRedirectCallback(url);
              }
              // No-op on Android
              await Browser.close();
            });
          }, [handleRedirectCallback]);

          // ..
        };// Import Capacitor's app and browser plugins, giving us access to `addListener` and `appUrlOpen`,
        // as well as the bits needed for Auth0 and React
        import { App as CapApp } from '@capacitor/app';
        import { Browser } from '@capacitor/browser';
        import { useEffect } from 'react';
        import { useAuth0 } from '@auth0/auth0-react';

        // ...

        const App: React.FC = () => {
          // Get the callback handler from the Auth0 React hook
          const { handleRedirectCallback } = useAuth0();

          useEffect(() => {
            // Handle the 'appUrlOpen' event and call `handleRedirectCallback`
            CapApp.addListener('appUrlOpen', async ({ url }) => {
              if (url.includes('state') && (url.includes('code') || url.includes('error'))) {
                await handleRedirectCallback(url);
              }
              // No-op on Android
              await Browser.close();
            });
          }, [handleRedirectCallback]);

          // ..
        };
        ```

        ```tsx user-profile.tsx lines 
        import { useAuth0 } from '@auth0/auth0-react';

        const Profile: React.FC = () => {
          const { user, isLoading } = useAuth0();

          // If the SDK is not ready, or a user is not authenticated, exit.
          if (isLoading || !user) return null;

          return (
            <div>
              <img src={user.picture} alt={user.name} />
              <h2>{user.name}</h2>
              <p>{user.email}</p>
            </div>
          );
        };

        export default Profile;
        ```
      </CodeGroup>
    </SideMenuSectionItem>

    <SideMenuSectionItem id={sections[4].id}>
      <CodeGroup>
        ```tsx login-button.tsx lines 
        import { useAuth0 } from '@auth0/auth0-react';
        import { Browser } from '@capacitor/browser';
        import { IonButton } from '@ionic/react';

        const LoginButton: React.FC = () => {
          const { loginWithRedirect } = useAuth0();

          const login = async () => {
            await loginWithRedirect({
              async openUrl(url) {
                 // Redirect using Capacitor's Browser plugin
                await Browser.open({
                  url,
                  windowName: "_self"
                });
              }
            });
          };

          return <IonButton onClick={login}>Log in</IonButton>;
        };

        export default LoginButton;
        ```

        ```tsx index.tsx lines 
        import React from 'react';
        import { createRoot } from 'react-dom/client';
        import { Auth0Provider } from '@auth0/auth0-react';
        import App from './App';

        const root = createRoot(document.getElementById('root'));

        root.render(
          <Auth0Provider
            domain="dev-gja8kxz4ndtex3rq.us.auth0.com"
            clientId="mz9iNEIo2PHu7oeh8QRt19ndTyyCIgai"
            useRefreshTokens={true}
            useRefreshTokensFallback={false}
            authorizationParams={{
              redirect_uri: "YOUR_PACKAGE_ID://dev-gja8kxz4ndtex3rq.us.auth0.com/capacitor/YOUR_PACKAGE_ID/callback"
            }}
          >
            <App />
          </Auth0Provider>
        );
        ```

        ```tsx logout-button.tsx lines 
        import { useAuth0 } from '@auth0/auth0-react';
        import { Browser } from '@capacitor/browser';
        import { IonButton } from '@ionic/react';

        // This should reflect the URL added earlier to your "Allowed Logout URLs" setting
        // in the Auth0 dashboard.
        const logoutUri = 'YOUR_PACKAGE_ID://dev-gja8kxz4ndtex3rq.us.auth0.com/capacitor/YOUR_PACKAGE_ID/callback';

        const LogoutButton: React.FC = () => {
          const { logout } = useAuth0();

          const doLogout = async () => {
            await logout({
              logoutParams: {
                returnTo: logoutUri
              },
              async openUrl(url) {
                 // Redirect using Capacitor's Browser plugin
                await Browser.open({
                  url,
                  windowName: "_self"
                });
              }
            });
          };

          return <IonButton onClick={doLogout}>Log out</IonButton>;
        };

        export default LogoutButton;
        ```

        ```tsx app.tsx lines 
        // Import Capacitor's app and browser plugins, giving us access to `addListener` and `appUrlOpen`,
        // as well as the bits needed for Auth0 and React
        import { App as CapApp } from '@capacitor/app';
        import { Browser } from '@capacitor/browser';
        import { useEffect } from 'react';
        import { useAuth0 } from '@auth0/auth0-react';

        // ...

        const App: React.FC = () => {
          // Get the callback handler from the Auth0 React hook
          const { handleRedirectCallback } = useAuth0();

          useEffect(() => {
            // Handle the 'appUrlOpen' event and call `handleRedirectCallback`
            CapApp.addListener('appUrlOpen', async ({ url }) => {
              if (url.includes('state') && (url.includes('code') || url.includes('error'))) {
                await handleRedirectCallback(url);
              }
              // No-op on Android
              await Browser.close();
            });
          }, [handleRedirectCallback]);

          // ..
        };// Import Capacitor's app and browser plugins, giving us access to `addListener` and `appUrlOpen`,
        // as well as the bits needed for Auth0 and React
        import { App as CapApp } from '@capacitor/app';
        import { Browser } from '@capacitor/browser';
        import { useEffect } from 'react';
        import { useAuth0 } from '@auth0/auth0-react';

        // ...

        const App: React.FC = () => {
          // Get the callback handler from the Auth0 React hook
          const { handleRedirectCallback } = useAuth0();

          useEffect(() => {
            // Handle the 'appUrlOpen' event and call `handleRedirectCallback`
            CapApp.addListener('appUrlOpen', async ({ url }) => {
              if (url.includes('state') && (url.includes('code') || url.includes('error'))) {
                await handleRedirectCallback(url);
              }
              // No-op on Android
              await Browser.close();
            });
          }, [handleRedirectCallback]);

          // ..
        };
        ```

        ```tsx user-profile.tsx lines 
        import { useAuth0 } from '@auth0/auth0-react';

        const Profile: React.FC = () => {
          const { user, isLoading } = useAuth0();

          // If the SDK is not ready, or a user is not authenticated, exit.
          if (isLoading || !user) return null;

          return (
            <div>
              <img src={user.picture} alt={user.name} />
              <h2>{user.name}</h2>
              <p>{user.email}</p>
            </div>
          );
        };

        export default Profile;
        ```
      </CodeGroup>
    </SideMenuSectionItem>

    <SideMenuSectionItem id={sections[5].id}>
      <CodeGroup>
        ```tsx app.tsx lines 
        // Import Capacitor's app and browser plugins, giving us access to `addListener` and `appUrlOpen`,
        // as well as the bits needed for Auth0 and React
        import { App as CapApp } from '@capacitor/app';
        import { Browser } from '@capacitor/browser';
        import { useEffect } from 'react';
        import { useAuth0 } from '@auth0/auth0-react';

        // ...

        const App: React.FC = () => {
          // Get the callback handler from the Auth0 React hook
          const { handleRedirectCallback } = useAuth0();

          useEffect(() => {
            // Handle the 'appUrlOpen' event and call `handleRedirectCallback`
            CapApp.addListener('appUrlOpen', async ({ url }) => {
              if (url.includes('state') && (url.includes('code') || url.includes('error'))) {
                await handleRedirectCallback(url);
              }
              // No-op on Android
              await Browser.close();
            });
          }, [handleRedirectCallback]);

          // ..
        };// Import Capacitor's app and browser plugins, giving us access to `addListener` and `appUrlOpen`,
        // as well as the bits needed for Auth0 and React
        import { App as CapApp } from '@capacitor/app';
        import { Browser } from '@capacitor/browser';
        import { useEffect } from 'react';
        import { useAuth0 } from '@auth0/auth0-react';

        // ...

        const App: React.FC = () => {
          // Get the callback handler from the Auth0 React hook
          const { handleRedirectCallback } = useAuth0();

          useEffect(() => {
            // Handle the 'appUrlOpen' event and call `handleRedirectCallback`
            CapApp.addListener('appUrlOpen', async ({ url }) => {
              if (url.includes('state') && (url.includes('code') || url.includes('error'))) {
                await handleRedirectCallback(url);
              }
              // No-op on Android
              await Browser.close();
            });
          }, [handleRedirectCallback]);

          // ..
        };
        ```

        ```tsx index.tsx lines 
        import React from 'react';
        import { createRoot } from 'react-dom/client';
        import { Auth0Provider } from '@auth0/auth0-react';
        import App from './App';

        const root = createRoot(document.getElementById('root'));

        root.render(
          <Auth0Provider
            domain="dev-gja8kxz4ndtex3rq.us.auth0.com"
            clientId="mz9iNEIo2PHu7oeh8QRt19ndTyyCIgai"
            useRefreshTokens={true}
            useRefreshTokensFallback={false}
            authorizationParams={{
              redirect_uri: "YOUR_PACKAGE_ID://dev-gja8kxz4ndtex3rq.us.auth0.com/capacitor/YOUR_PACKAGE_ID/callback"
            }}
          >
            <App />
          </Auth0Provider>
        );
        ```

        ```tsx login-button.tsx lines 
        import { useAuth0 } from '@auth0/auth0-react';
        import { Browser } from '@capacitor/browser';
        import { IonButton } from '@ionic/react';

        const LoginButton: React.FC = () => {
          const { loginWithRedirect } = useAuth0();

          const login = async () => {
            await loginWithRedirect({
              async openUrl(url) {
                 // Redirect using Capacitor's Browser plugin
                await Browser.open({
                  url,
                  windowName: "_self"
                });
              }
            });
          };

          return <IonButton onClick={login}>Log in</IonButton>;
        };

        export default LoginButton;
        ```

        ```tsx logout-button.tsx lines 
        import { useAuth0 } from '@auth0/auth0-react';
        import { Browser } from '@capacitor/browser';
        import { IonButton } from '@ionic/react';

        // This should reflect the URL added earlier to your "Allowed Logout URLs" setting
        // in the Auth0 dashboard.
        const logoutUri = 'YOUR_PACKAGE_ID://dev-gja8kxz4ndtex3rq.us.auth0.com/capacitor/YOUR_PACKAGE_ID/callback';

        const LogoutButton: React.FC = () => {
          const { logout } = useAuth0();

          const doLogout = async () => {
            await logout({
              logoutParams: {
                returnTo: logoutUri
              },
              async openUrl(url) {
                 // Redirect using Capacitor's Browser plugin
                await Browser.open({
                  url,
                  windowName: "_self"
                });
              }
            });
          };

          return <IonButton onClick={doLogout}>Log out</IonButton>;
        };

        export default LogoutButton;
        ```

        ```tsx user-profile.tsx lines 
        import { useAuth0 } from '@auth0/auth0-react';

        const Profile: React.FC = () => {
          const { user, isLoading } = useAuth0();

          // If the SDK is not ready, or a user is not authenticated, exit.
          if (isLoading || !user) return null;

          return (
            <div>
              <img src={user.picture} alt={user.name} />
              <h2>{user.name}</h2>
              <p>{user.email}</p>
            </div>
          );
        };

        export default Profile;
        ```
      </CodeGroup>
    </SideMenuSectionItem>

    <SideMenuSectionItem id={sections[6].id}>
      <CodeGroup>
        ```tsx logout-button.tsx lines 
        import { useAuth0 } from '@auth0/auth0-react';
        import { Browser } from '@capacitor/browser';
        import { IonButton } from '@ionic/react';

        // This should reflect the URL added earlier to your "Allowed Logout URLs" setting
        // in the Auth0 dashboard.
        const logoutUri = 'YOUR_PACKAGE_ID://dev-gja8kxz4ndtex3rq.us.auth0.com/capacitor/YOUR_PACKAGE_ID/callback';

        const LogoutButton: React.FC = () => {
          const { logout } = useAuth0();

          const doLogout = async () => {
            await logout({
              logoutParams: {
                returnTo: logoutUri
              },
              async openUrl(url) {
                 // Redirect using Capacitor's Browser plugin
                await Browser.open({
                  url,
                  windowName: "_self"
                });
              }
            });
          };

          return <IonButton onClick={doLogout}>Log out</IonButton>;
        };

        export default LogoutButton;
        ```

        ```tsx index.tsx lines 
        import React from 'react';
        import { createRoot } from 'react-dom/client';
        import { Auth0Provider } from '@auth0/auth0-react';
        import App from './App';

        const root = createRoot(document.getElementById('root'));

        root.render(
          <Auth0Provider
            domain="dev-gja8kxz4ndtex3rq.us.auth0.com"
            clientId="mz9iNEIo2PHu7oeh8QRt19ndTyyCIgai"
            useRefreshTokens={true}
            useRefreshTokensFallback={false}
            authorizationParams={{
              redirect_uri: "YOUR_PACKAGE_ID://dev-gja8kxz4ndtex3rq.us.auth0.com/capacitor/YOUR_PACKAGE_ID/callback"
            }}
          >
            <App />
          </Auth0Provider>
        );
        ```

        ```tsx login-button.tsx lines 
        import { useAuth0 } from '@auth0/auth0-react';
        import { Browser } from '@capacitor/browser';
        import { IonButton } from '@ionic/react';

        const LoginButton: React.FC = () => {
          const { loginWithRedirect } = useAuth0();

          const login = async () => {
            await loginWithRedirect({
              async openUrl(url) {
                 // Redirect using Capacitor's Browser plugin
                await Browser.open({
                  url,
                  windowName: "_self"
                });
              }
            });
          };

          return <IonButton onClick={login}>Log in</IonButton>;
        };

        export default LoginButton;
        ```

        ```tsx app.tsx lines 
        // Import Capacitor's app and browser plugins, giving us access to `addListener` and `appUrlOpen`,
        // as well as the bits needed for Auth0 and React
        import { App as CapApp } from '@capacitor/app';
        import { Browser } from '@capacitor/browser';
        import { useEffect } from 'react';
        import { useAuth0 } from '@auth0/auth0-react';

        // ...

        const App: React.FC = () => {
          // Get the callback handler from the Auth0 React hook
          const { handleRedirectCallback } = useAuth0();

          useEffect(() => {
            // Handle the 'appUrlOpen' event and call `handleRedirectCallback`
            CapApp.addListener('appUrlOpen', async ({ url }) => {
              if (url.includes('state') && (url.includes('code') || url.includes('error'))) {
                await handleRedirectCallback(url);
              }
              // No-op on Android
              await Browser.close();
            });
          }, [handleRedirectCallback]);

          // ..
        };// Import Capacitor's app and browser plugins, giving us access to `addListener` and `appUrlOpen`,
        // as well as the bits needed for Auth0 and React
        import { App as CapApp } from '@capacitor/app';
        import { Browser } from '@capacitor/browser';
        import { useEffect } from 'react';
        import { useAuth0 } from '@auth0/auth0-react';

        // ...

        const App: React.FC = () => {
          // Get the callback handler from the Auth0 React hook
          const { handleRedirectCallback } = useAuth0();

          useEffect(() => {
            // Handle the 'appUrlOpen' event and call `handleRedirectCallback`
            CapApp.addListener('appUrlOpen', async ({ url }) => {
              if (url.includes('state') && (url.includes('code') || url.includes('error'))) {
                await handleRedirectCallback(url);
              }
              // No-op on Android
              await Browser.close();
            });
          }, [handleRedirectCallback]);

          // ..
        };
        ```

        ```tsx user-profile.tsx lines 
        import { useAuth0 } from '@auth0/auth0-react';

        const Profile: React.FC = () => {
          const { user, isLoading } = useAuth0();

          // If the SDK is not ready, or a user is not authenticated, exit.
          if (isLoading || !user) return null;

          return (
            <div>
              <img src={user.picture} alt={user.name} />
              <h2>{user.name}</h2>
              <p>{user.email}</p>
            </div>
          );
        };

        export default Profile;
        ```
      </CodeGroup>
    </SideMenuSectionItem>

    <SideMenuSectionItem id={sections[7].id}>
      <CodeGroup>
        ```tsx user-profile.tsx lines 
        import { useAuth0 } from '@auth0/auth0-react';

        const Profile: React.FC = () => {
          const { user, isLoading } = useAuth0();

          // If the SDK is not ready, or a user is not authenticated, exit.
          if (isLoading || !user) return null;

          return (
            <div>
              <img src={user.picture} alt={user.name} />
              <h2>{user.name}</h2>
              <p>{user.email}</p>
            </div>
          );
        };

        export default Profile;
        ```

        ```tsx index.tsx lines 
        import React from 'react';
        import { createRoot } from 'react-dom/client';
        import { Auth0Provider } from '@auth0/auth0-react';
        import App from './App';

        const root = createRoot(document.getElementById('root'));

        root.render(
          <Auth0Provider
            domain="dev-gja8kxz4ndtex3rq.us.auth0.com"
            clientId="mz9iNEIo2PHu7oeh8QRt19ndTyyCIgai"
            useRefreshTokens={true}
            useRefreshTokensFallback={false}
            authorizationParams={{
              redirect_uri: "YOUR_PACKAGE_ID://dev-gja8kxz4ndtex3rq.us.auth0.com/capacitor/YOUR_PACKAGE_ID/callback"
            }}
          >
            <App />
          </Auth0Provider>
        );
        ```

        ```tsx login-button.tsx lines 
        import { useAuth0 } from '@auth0/auth0-react';
        import { Browser } from '@capacitor/browser';
        import { IonButton } from '@ionic/react';

        const LoginButton: React.FC = () => {
          const { loginWithRedirect } = useAuth0();

          const login = async () => {
            await loginWithRedirect({
              async openUrl(url) {
                 // Redirect using Capacitor's Browser plugin
                await Browser.open({
                  url,
                  windowName: "_self"
                });
              }
            });
          };

          return <IonButton onClick={login}>Log in</IonButton>;
        };

        export default LoginButton;
        ```

        ```tsx logout-button.tsx lines 
        import { useAuth0 } from '@auth0/auth0-react';
        import { Browser } from '@capacitor/browser';
        import { IonButton } from '@ionic/react';

        // This should reflect the URL added earlier to your "Allowed Logout URLs" setting
        // in the Auth0 dashboard.
        const logoutUri = 'YOUR_PACKAGE_ID://dev-gja8kxz4ndtex3rq.us.auth0.com/capacitor/YOUR_PACKAGE_ID/callback';

        const LogoutButton: React.FC = () => {
          const { logout } = useAuth0();

          const doLogout = async () => {
            await logout({
              logoutParams: {
                returnTo: logoutUri
              },
              async openUrl(url) {
                 // Redirect using Capacitor's Browser plugin
                await Browser.open({
                  url,
                  windowName: "_self"
                });
              }
            });
          };

          return <IonButton onClick={doLogout}>Log out</IonButton>;
        };

        export default LogoutButton;
        ```

        ```tsx app.tsx lines 
        // Import Capacitor's app and browser plugins, giving us access to `addListener` and `appUrlOpen`,
        // as well as the bits needed for Auth0 and React
        import { App as CapApp } from '@capacitor/app';
        import { Browser } from '@capacitor/browser';
        import { useEffect } from 'react';
        import { useAuth0 } from '@auth0/auth0-react';

        // ...

        const App: React.FC = () => {
          // Get the callback handler from the Auth0 React hook
          const { handleRedirectCallback } = useAuth0();

          useEffect(() => {
            // Handle the 'appUrlOpen' event and call `handleRedirectCallback`
            CapApp.addListener('appUrlOpen', async ({ url }) => {
              if (url.includes('state') && (url.includes('code') || url.includes('error'))) {
                await handleRedirectCallback(url);
              }
              // No-op on Android
              await Browser.close();
            });
          }, [handleRedirectCallback]);

          // ..
        };// Import Capacitor's app and browser plugins, giving us access to `addListener` and `appUrlOpen`,
        // as well as the bits needed for Auth0 and React
        import { App as CapApp } from '@capacitor/app';
        import { Browser } from '@capacitor/browser';
        import { useEffect } from 'react';
        import { useAuth0 } from '@auth0/auth0-react';

        // ...

        const App: React.FC = () => {
          // Get the callback handler from the Auth0 React hook
          const { handleRedirectCallback } = useAuth0();

          useEffect(() => {
            // Handle the 'appUrlOpen' event and call `handleRedirectCallback`
            CapApp.addListener('appUrlOpen', async ({ url }) => {
              if (url.includes('state') && (url.includes('code') || url.includes('error'))) {
                await handleRedirectCallback(url);
              }
              // No-op on Android
              await Browser.close();
            });
          }, [handleRedirectCallback]);

          // ..
        };
        ```
      </CodeGroup>
    </SideMenuSectionItem>
  </SideMenu>
</Recipe>
