How to embed Amazon Connect's standard CCP in Next.js
日本語verはこちら
Introduction.
In this case, I would like to embed Amazon Connect's standard CCP into a Next.js application to create an application that allows you to visually see which queue an incoming call came through.
Next.js is a framework that is gaining momentum right now and I would love to use it.
At first I thought Next.js was not compatible with amazon-connect-streams because of its library, but I made a trial application to study Next.js and found it works, so I would like to introduce it here.
This article does not claim that the combination of Next.js and amazon-connect-streams is absolutely safe, so if you intend to use it in production, we recommend that you conduct a PoC to see if your requirements can be met.
Please note that although this article includes a video, we did not deploy to Vercel or other hosting services, and all checks were done locally. Please note that this article is not deployed to Vercel or other hosting services, etc., and all checks were done locally.
Get started
First, build the Next.js environment.
For your information, the author's environment is as follows
Node.js: ^20
TypeScript: ^5
React: ^19
Next: 15.1.3
OS: MacOS
First, use the create-next-app command.
npx create-next-app@latest
What is your project named? nextjs-amazon-connect-custom
Would you like to use TypeScript? Yes
Would you like to use ESLint? Yes
Would you like to use Tailwind CSS? Yes
Would you like your code inside a `src/` directory? Yes
Would you like to use App Router? (recommended) Yes
Would you like to use Turbopack for `next dev`? Yes
Would you like to customize the import alias (`@/*` by default)? Yes
What import alias would you like configured? @/*
Next, install the amazon connect streams library.
yarn add amazon-connect-streams
Now you are ready to go.
FrontEnd implementation
The code created earlier in this article is available in this repository if you would like to review the entire code.
You can also clone this code and enter the Amazon Connect instance alias name in the environment variable to actually try it locally.
If you do this, please add a local server such as localhost:3000 to the approved origin in the Amazon Connect instance settings.
Please note that if you forget to do so, it will not work.
In this case, we use AppRouter instead of Page Router.
Now edit the default layout.ts.
import type { Metadata } from "next";
import { FC } from "react";
import "./globals.css";
export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
const RootLayout: FC<{
children: React.ReactNode;
}> = ({ children }) => {
return (
<html lang="ja">
<body>
<main className="w-screen h-screen">{children}</main>
</body>
</html>
);
};
export default RootLayout;
Next, set page.tsx as follows
import CCP from "@/components/ui/CCP";
import { FC } from "react";
const Home: FC = () => {
return<CCP/>;
};
export default Home;
The next CCP component to be created will be Client Components.
"use client";
import { useRef, useEffect, useState } from "react";
const CCP = ({}) => {
const ccpContainerEl = useRef<HTMLDivElement>(null);
const [queue, setQueue] = useState<string | null>(null);
useEffect(() => {
require("amazon-connect-streams");
if (ccpContainerEl.current) {
connect.core.initCCP(ccpContainerEl.current, {
ccpUrl: `https://${process.env.NEXT_PUBLIC_AMAZON_CONNECT_INSTANCE_NAME}.my.connect.aws/ccp-v2`,
loginUrl: `https://${process.env.NEXT_PUBLIC_AMAZON_CONNECT_INSTANCE_NAME}.my.connect.aws/ccp-v2/login`,
loginPopup: true,
loginPopupAutoClose: true,
softphone: {
allowFramedSoftphone: true,
},
});
connect.agent(async (agent: any) => {
const agentConf = agent.getConfiguration();
console.log(agentConf);
agent.onStateChange((state: any) => {
console.log(state);
});
agent.onError((error: any) => {
console.log(error);
});
});
connect.contact(async (contact: any) => {
contact.onConnected(() => {
console.log("connected");
const queue = contact.getQueue();
setQueue(queue.name);
});
contact.onEnded(() => {
console.log("ended");
setQueue(null);
});
});
}
return () => {
connect.core.terminate();
ccpContainerEl.current = null;
};
}, []);
useEffect(() => {
console.log(queue);
}, [queue]);
return (
<>
<div className="h-2rem text-center text-2xl text-gray-750">
Queue: {queue || "非通話状態です"}
</div>
<div
id="ccp-container"
ref={ccpContainerEl}
className="h-[calc(100vh-2rem)] w-full"
/>
</>
);
};
export default CCP;
One point to note is to import amazon-connect-streams in the contents of useEffect.
I have referred to the Issue comments on amazon connect streams, which discusses what to watch out for when using Next.js.
This should work and I would like to try it.
Operation check
It worked like this.
As you can see, it is possible to dynamically retrieve information from amazon connect streams, so I think it is possible to extend the functionality.
In addition to embedding the standard CCP, you can also create your own UI, so if you want to implement requirements that cannot be realized with the standard CCP UI, please try it out.
Finally
Thank you for reading this far.
We hope this article has been helpful to someone.
Discussion