> ## Documentation Index
> Fetch the complete documentation index at: https://flatfileinc-docs-update-8de3b114-e6aa-4417-a753-2ecef733a0d.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart Portal 2 Upgrade

> Moving on up... to the Platform

## Overview

This guide is designed to help you quickly transition from Portal 2 to the new
and improved Platform. Using our
[V2 Shim package](https://www.npmjs.com/package/@flatfile/v2-shims) for
assistance with the transition, you can get started on the new Platform within a
few hours. To help you compare and contrast between your Portal 2 implementation
and the Platform implementation, we created
[this Github Repository](https://github.com/FlatFilers/Upgrade-Portal) as a way
to help you see the upgrade process from beginning to the end.

## Before You Begin

With the new Platform, comes a brand new place to sign up for it. Before getting
started on your upgrade, you'll need to [sign up](https://platform.flatfile.com)
for a new account.

## Install the V2 Shims package

Before you can start using all the wonderful tools in this guide to implement
Flatfile, you'll need to install a couple of packages, the V2 Shims and Flatfile
API packages.

<Note>
  If you are using our `@flatfile/react` package, be sure to install version
  7.9.1 or higher to get the latest Platform React component.
</Note>

<CodeGroup>
  ```bash JavaScript
  npm install @flatfile/v2-shims @flatfile/api
  ```

  ```bash React
  npm install @flatfile/v2-shims @flatfile/api @flatfile/react@7.9.1
  ```
</CodeGroup>

## Convert Your Config

The Portal 2 configuration is what contains your settings and fields in your
Portal implementation.

<CodeGroup>
  ```js JavaScript
  const importer = new FlatfileImporter(
      "YOUR_LICENSE_KEY",
      { } // This is your configuration object
  )
  ```

  ```jsx React
  <FlatfileButton
      licenseKey="YOUR_LICENSE_KEY"
      customer={{ userId: '1234' }}
      settings={} // This is your configuration object
  >
      Import Contacts
  </FlatfileButton>
  ```
</CodeGroup>

You'll be able to use this configuration object with the V2 Shims package to
configure your new implementation. Keep in mind that the below snippets use a
couple of new concepts like a [Job](/learning-center/concepts/jobs) and
[Listener](/learning-center/tutorials/projects/meet-the-listener). While you don't need to learn about
these to get started, they are useful for adding new functionality onto your
importer at some point in the future.

<CodeGroup>
  ```js Portal 2 JavaScript
  import FlatfileImporter from '@flatfile/adapter'

  const config = {
      type: 'Contacts',
      fields: [
          {
              key: 'name',
              label: 'Name',
              description: 'Contact name',
              validators: [
                  { validate: 'required' }
              ]
          }
      ]
  }

  const importer = new FlatfileImporter('LICENSE_KEY', config)
  ```

  ```js Platform JavaScript
  import { initializeFlatfile } from "@flatfile/javascript";
  import { schemas } from "./schemas";
  import { listener } from "../listeners/listener";
  import { configToBlueprint } from "@flatfile/v2-shims";

  const config = {
      type: 'Contacts',
      fields: [
          {
              key: 'name',
              label: 'Name',
              description: 'Contact name',
              validators: [
                  { validate: 'required' }
              ]
          }
      ]
  }

  window.openFlatfile = ({publishableKey}) => {
      if (!publishableKey) {
          throw new Error(
              "You must provide a publishable key - pass through in index.html"
          );
      }

      const flatfileOptions = {
          publishableKey,
          name: 'Contact Space',
          workbook: configToBlueprint(config),
          listener,
          sidebarConfig: {
              showSidebar: false,
          },
          // Additional props...
      };

      initializeFlatfile(flatfileOptions);
  };
  ```

  ```jsx Portal 2 React
  import { FlatfileButton } from "@flatfile/react"

  const config = {
      type: 'Contacts',
      fields: [
          {
              key: 'name',
              label: 'Name',
              description: 'Contact name',
              validators: [
                  {validate: 'required'}
              ]
          }
      ]
  }

  export default function App() {
      return (
          <div className="App">
              <FlatfileButton
                  licenseKey="YOUR_V2_LICENSE_KEY"
                  customer={{ userId: '1234'}}
                  settings={config}
              >
              Import Contacts
              </FlatfileButton>
          </div>
      )
  }
  ```

  ```js Platform React
  import { listener } from "./listener";
  import { configToBlueprint } from "@flatfile/v2-shims";
  import { FlatfileProvider, Space, Workbook } from "@flatfile/react";
  import { useFlatfile, useListener } from "@flatfile/react";
  import { Flatfile } from "@flatfile/api";

  const FFApp = () => {
      const { open, openPortal, closePortal } = useFlatfile();

      // import file directly
      useListener(listener, []);

      return (
          <div className={"App"}>
          <div className={"contract"}>
              <button
                  onClick={() => {
                      open ? closePortal() : openPortal();
                  }}
              >
              {open ? "OPEN" : "CLOSE"} PORTAL
              </button>
          </div>

          <Space
              config={{
                  metadata: {
                      sidebarConfig: {
                          showSidebar: true,
                      },
                  },
              }}
          >
              <Workbook
              config={
                  configToBlueprint(config as any) as Flatfile.CreateWorkbookConfig
              }
              onSubmit={(sheet) => {
                  console.log("onSubmit", { sheet });
              }}
              ></Workbook>
          </Space>
          </div>
      );
  };

  const App = () => {
      return (
          <FlatfileProvider
              publishableKey={"pk_1234"}
              config={{
                  displayAsModal: true,
              }}
          >
          <FFApp />
          </FlatfileProvider>
      );
  };

  export default App;
  ```
</CodeGroup>

## Converting your Record Hooks

If you're transitioning from a V2 Record Hook to a Platform Record Hook in your
code, you can make the conversion by simply extracting and wrapping your
existing Record Hook code in the V2 Shim `convertHook` method.

<Note>
  If you're using V2 Record Hooks `mode` to split hooks on "init" or on
  "change", Platform does not have this mode functionality. It does, however,
  have better overall hooks performance and a new [Bulk Record
  Hook](https://flatfile.com/plugins/plugin-record-hook#additional-options)
  method that make `mode` unnecessary.
</Note>

<CodeGroup>
  ```js Portal 2 JavaScript
  const importer = new FlatfileImporter('LICENSE_KEY', config)

  const recordHooksCallback = async (record) => {
      let out = {};

      if (record.firstName && !record.lastName) {
          out.lastName = {
              value: 'Rock',
              info: [
                  {
                      message: 'No last name provided so welcome to the Rock fam.',
                      level: 'warning'
                  }
              ]
          }
      }
      return out;
  }

  importer.registerRecordHook(recordHooksCallback);
  ```

  ```js Platform
  import { convertHook } from "@flatfile/v2-shims";

  export default function (listener) {
      listener.filter({ job: "space:configure" }, (configure) => {
          // code from above
      });
      // new Record Hook code

      listener.use(
          recordHook('TestSheet', async (record, event) => {
              return convertHook(recordHooks)(record)
          })
      )
  }
  ```

  ```jsx Portal 2 React
  import { FlatfileButton } from "@flatfile/react"
  import flatfileConfig from "./config"

  const recordHooksCallback = async (record) => {
      let out = {};

      if (record.firstName && !record.lastName) {
          out.lastName = {
              value: 'Rock',
              info: [
                  {
                      message: 'No last name provided so welcome to the Rock fam.',
                      leval: 'warning'
                  }
              ]
          }
      }
      return out;
  }

  export default function App() {
      return (
          <div className="App">
              <FlatfileButton
                  licenseKey="YOUR_V2_LICENSE_KEY"
                  customer={{ userId: '1234'}}
                  settings={flatfileConfig}
                  onRecordInit={recordHooksCallback}
                  onRecordChange={recordHooksCallback}
              >
              Import Contacts
              </FlatfileButton>
          </div>
      )
  }
  ```

  ```jsx Platform React - Embed
  // Be sure to use @flatfile/react 7.9.1 or later
  import { listener } from "./listener";
  import { configToBlueprint } from "@flatfile/v2-shims";
  import { FlatfileProvider, Space, Workbook } from "@flatfile/react";
  import { useFlatfile, useListener } from "@flatfile/react";
  import { Flatfile } from "@flatfile/api";

  const FFApp = () => {
      const { open, openPortal, closePortal } = useFlatfile();

      // import file directly
      useListener(listener, []);

      return (
          <div className={"App"}>
          <div className={"contract"}>
              <button
                  onClick={() => {
                      open ? closePortal() : openPortal();
                  }}
              >
              {open ? "OPEN" : "CLOSE"} PORTAL
              </button>
          </div>

          <Space
              config={{
                  metadata: {
                      sidebarConfig: {
                          showSidebar: true,
                      },
                  },
              }}
          >
              <Workbook
              config={
                  configToBlueprint(config as any) as Flatfile.CreateWorkbookConfig
              }
              onSubmit={(sheet) => {
                  console.log("onSubmit", { sheet });
              }}
              ></Workbook>
          </Space>
          </div>
      );
  };

  const App = () => {
      return (
          <FlatfileProvider
              publishableKey={"pk_1234"}
              config={{
                  displayAsModal: true,
              }}
          >
          <FFApp />
          </FlatfileProvider>
      );
  };

  export default App;
  ```

  ```js Platform React - Listener
  import { convertHook } from "@flatfile/v2-shims";

  const recordHooksCallback = async (record) => {
      let out = {};

      if (record.firstName && !record.lastName) {
          out.lastName = {
              value: 'Rock',
              info: [
                  {
                      message: 'No last name provided so welcome to the Rock fam.',
                      leval: 'warning'
                  }
              ]
          }
      }
      return out;
  }

  export default function (listener) {
      listener.filter({ job: "space:configure" }, (configure) => {
          // code from above
      });
      // new Record Hook code

      listener.use(
          recordHook('Contracts', async (record, event) => {
              return convertHook(recordHooksCallback)(record)
          })
      )
  }
  ```
</CodeGroup>

<Note>
  If you're using React and want more ideas on how you can implement your
  listener code or add plugins, check out our full React documentation
  [here](/learning-center/tutorials/projects/meet-the-listener).
</Note>
