Skip to main content
The Loan Application Element is a complete end-to-end mortgage loan application experience. This guide shows you how to integrate it into your application.

Prerequisites

Before building the Loan Application Element, ensure you have:
  1. Set up authentication - Configured your backend to handle Pylon authorization requests
  2. Installed the Elements library:
npm install @pylonlending/react-elements --save

Basic implementation

Here’s a minimal implementation of the Loan Application Element:
// Import the Loan Application Element
import { LoanApplicationElement } from "@pylonlending/react-elements";

// Create a function that returns a Promise<AuthLease>
// This should fetch the results of your auth handler endpoint
const fetchPylonAuthLease = async (): Promise<AuthLease> => {
  const response = await fetch("/auth/pylon");
  return response.json();
};

<YourApplication>
  <LoanApplicationElement
    // Include your function that returns a Promise<AuthLease>
    authLeaseCallback={fetchPylonAuthLease}
  />
</YourApplication>

Required properties

PropertyTypeDescription
authLeaseCallbackAuthLeaseCallbackA function that fetches the results of your authentication route. Must return a Promise<AuthLease>.

Loading an existing loan

To load an existing loan application, pass the loanId prop:
<LoanApplicationElement
  authLeaseCallback={fetchPylonAuthLease}
  loanId="loan_12345"
/>
To start a new loan application, omit the loanId prop or set it to undefined.

Pre-filling data with the GraphQL API

You can use the GraphQL API to pre-fill borrower information before initializing the Loan Application Element. When you create a loan and add borrower data (personal information, income, assets, property details, etc.) via the API, that data will automatically be pre-filled in the Element when it’s initialized. This is useful for:
  • Streamlined onboarding - Pre-fill data you already have from your system
  • Hybrid workflows - Collect some information in your own UI, then let Elements handle the rest
  • Better UX - Borrowers can review and complete pre-filled information rather than starting from scratch
See Loading loans for a complete example of pre-filling data via the API.

Content Security Policy

If you’re using a Content Security Policy, add these directives:
default-src https://api.{customer-id}.{env}.pylon.mortgage
frame-src https://api.{customer-id}.{env}.pylon.mortgage
script-src https://api.{customer-id}.{env}.pylon.mortgage/elements/pylon.js
connect-src https://api.{customer-id}.{env}.pylon.mortgage
Replace {customer-id} with your customer ID and {env} with test or prod.

Important notes

All props passed to the LoanApplicationElement should be const-they should not change after the Element’s first render. If props change, they will have no effect and will not be updated inside the Element.

Optional properties

PropertyTypeDescription
loanIdstringThe ID of an existing loan to load. Omit or set to undefined to start a new application.
themeThemeTheme configuration object to customize the Element’s appearance. See Theming for details.

Complete example with all features

Here’s a complete example that includes theming and demonstrates how to handle loan completion:
import { LoanApplicationElement } from "@pylonlending/react-elements";
import { useState, useEffect } from "react";

function LoanApplicationPage() {
  const [loanId, setLoanId] = useState<string | undefined>();
  const [showDashboard, setShowDashboard] = useState(false);

  const fetchPylonAuthLease = async (): Promise<AuthLease> => {
    const response = await fetch("/auth/pylon");
    return response.json();
  };

  // Poll for loan completion
  useEffect(() => {
    if (!loanId) return;

    const interval = setInterval(async () => {
      const query = `
        query GetLoanStatus($id: ID!) {
          loan(id: $id) {
            id
            submitted
          }
        }
      `;

      const response = await fetch("https://pylon.mortgage/graphql", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${accessToken}`,
        },
        body: JSON.stringify({ query, variables: { id: loanId } }),
      });

      const { data } = await response.json();
      if (data.loan?.submitted) {
        setShowDashboard(true);
        clearInterval(interval);
      }
    }, 30 * 60 * 1000); // Poll every 30 minutes

    return () => clearInterval(interval);
  }, [loanId]);

  const theme = {
    Global: {
      fonts: {
        fontFamily: "Inter, sans-serif",
        fontUrls: [
          "https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap",
        ],
      },
      colors: {
        core: {
          primary: "#0066CC",
        },
      },
    },
  };

  if (showDashboard && loanId) {
    return <BorrowerDashboardElement loanId={loanId} authLeaseCallback={fetchPylonAuthLease} />;
  }

  return (
    <LoanApplicationElement
      authLeaseCallback={fetchPylonAuthLease}
      loanId={loanId}
      theme={theme}
    />
  );
}

Next steps