Get Started

Octolane AI Company Identify Widget

We will be building the company identify widget with custom message. We will be using Next.js (App Router) for this example with Tailwind css, Headless UI for smooth transitioning, and heroicons which is completely free. You can use any framework you like.

We will be need to implement just two typescript files. One is for the widget component and the other is for the API route which will basically call the Octolane API and return the magic results.

Widget Component

Let’s install the dependencies first, if there is missing something in your project:


npm install @headlessui/react @heroicons/react tailwindcss heroicons

NB. We are skipping the tailwind setup here. You can follow the tailwind setup

Create a file called CompanyIdentifyWidget.tsx and add the following code:

"use client";

import { Transition } from "@headlessui/react";
import { XMarkIcon } from "@heroicons/react/24/outline";
import { Fragment, useCallback, useEffect, useState } from "react";

import { getLogoURLByDomain } from "~/core/generic/common-utils";

/* eslint-disable @next/next/no-img-element */

type IdentifiedCompany = {
  domain: string;
  company_name: string;
};

const OctolaneCompanyIdentifyAtert = () => {
  const [companyData, setCompanyData] = useState<IdentifiedCompany | null>(
    null,
  );
  const [showAlert, setShowAlert] = useState(false);

  // This will call our internal nextjs API route to get the company data
  const identifyCompany = useCallback(async () => {
    const response = await fetch("/api/company-identify");
    const data = await response.json();
    if (data) {
      setShowAlert(true);
      setCompanyData(data.data);
    }
  }, []);

  // Calling the identify company function on component mount
  useEffect(() => {
    identifyCompany();
  }, [identifyCompany]);

  return (
    <div className="pointer-events-none fixed inset-6 flex items-end px-4 py-6 sm:items-start sm:p-6">
      <div className="flex w-full flex-col items-center space-y-4 sm:items-end">
        <Transition
          show={showAlert}
          as={Fragment}
          enter="transform ease-out duration-300 transition"
          enterFrom="translate-y-2 opacity-0 sm:translate-y-0 sm:translate-x-2"
          enterTo="translate-y-0 opacity-100 sm:translate-x-0"
          leave="transition ease-in duration-100"
          leaveFrom="opacity-100"
          leaveTo="opacity-0"
        >
          <div className="pointer-events-auto w-full max-w-sm rounded-lg bg-white shadow-lg ring-1 ring-black ring-opacity-5">
            <div className="p-4">
              <div className="flex items-start">
                <div className="flex-shrink-0 pt-0.5">
                  <img
                    className="h-10 w-10 rounded-md"
                    width={40}
                    height={40}
                    src={`https://logo.clearbit.com/${companyData?.domain}`}
                    alt={`Octolane AI found ${companyData?.company_name} through ip enrichment`}
                  />
                </div>
                <div className="ml-3 w-0 flex-1">
                  <p className="text-sm font-medium text-gray-900">
                    Hey {companyData?.company_name}! πŸ‘‹
                  </p>
                  <p className="mt-1 text-sm text-gray-500">
                    Identify visiting companies (like we did!) and convert
                    anonymous traffic into customers!
                  </p>
                  <div className="mt-4 flex">
                    <button
                      type="button"
                      className="inline-flex items-center rounded-md bg-zinc-800 px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-zinc-900 focus:outline-none focus:ring-2 focus:ring-zinc-500 focus:ring-offset-2"
                      onClick={() => {
                        // Implement this
                      }}
                    >
                      Reveal My Visitors
                    </button>
                    <button
                      type="button"
                      className="ml-3 text-sm font-semibold text-gray-500 hover:text-gray-900 hover:underline"
                      onClick={() => setShowAlert(false)}
                    >
                      No Thanks
                    </button>
                  </div>
                </div>
                <div className="ml-4 flex flex-shrink-0">
                  <button
                    type="button"
                    className="inline-flex rounded-md bg-white text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
                    onClick={() => setShowAlert(false)}
                  >
                    <span className="sr-only">Close</span>
                    <XMarkIcon className="h-5 w-5" aria-hidden="true" />
                  </button>
                </div>
              </div>
            </div>
          </div>
        </Transition>
      </div>
    </div>
  );
};

export default OctolaneCompanyIdentifyAtert;

Feel free to replace the used icon from heroicons with your own icon. You can also replace the tailwindcss classes with your own classes.

API Route

Create a file called /api/company-identify/route.ts and add the following code:

import { headers } from "next/headers";
import { NextResponse } from "next/server";

export const GET = async (request: Request) => {
  const apiHeaders = {
    "Content-Type": "application/json",
    "x-api-key": "<Replace-your-octolane-api-key>",
  };

  const headersList = headers();
  /** 
   * You will not see any ip address while working on localhost.
   * You will need to deploy your app to see the ip address. But, alternatively you can use a 
   * dummy ip address for testing purpose.
   */
  const ip = headersList.get("x-forwarded-for");

  if (!ip) {
    return NextResponse.json({
      success: false,
      statusCode: 400,
      message: "IP address is not found",
    });
  }

  try {
    const response = await fetch(
      `https://enrich.octolane.com/v1/ip-to-company?ip=${ip}`,
      {
        method: "GET",
        headers: apiHeaders,
      },
    );
    const data = await response.json();

    return NextResponse.json({
      success: true,
      statusCode: 200,
      data: data.data,
    });
  } catch (error) {
    return NextResponse.json({
      success: false,
      statusCode: 404,
      message: "Couldn't identified company",
    });
  }
};

You will be need to replace the <Replace-your-octolane-api-key> with your own API key. You can get the API key from your dashboard.

Hope these two files will help you to customize your web traffic experience. If you have any questions, please feel free to reach out to us.

Talk directly to our co-founders by emailing one@octolane.com. We read every single email and reply to them personally.

Our pro customers have Slack connect with us and we help them with migrations and give more direct support.

You can also follow our team on Twitter for the latest updates: CoffeeWithOne or you can follow our company Twitter: Octolane_App.