Quick Start - Next.js

Get up and running with Importly in your Next.js application using webhook-driven architecture for optimal performance.

Setup

First, install the necessary dependencies:

bash
1npm install axios

1. Get Your API Key

  1. Create an Account at Importly.io
  2. Find your API Key via the api key page
  3. Add it to your environment variables:
bash
1# .env.local
2IMPORTLY_API_KEY=your_api_key_here
3NEXT_PUBLIC_WEBHOOK_URL=https://your-domain.com/api/importly/webhook
4NEXT_PUBLIC_IMPORTLY_API_URL=https://api.importly.io

2. Create Importly Client

Create a utility file for your Importly client:

javascript
1// lib/importly.js
2import axios from "axios";
3
4class ImportlyClient {
5 constructor(apiKey) {
6 this.apiKey = apiKey;
7 this.baseURL = process.env.NEXT_PUBLIC_IMPORTLY_API_URL;
8 }
9
10 async importMedia(url, options = {}) {
11 const {
12 includeVideo = true,
13 includeAudio = true,
14 videoQuality = "1080p",
15 audioQuality = "medium",
16 webhookUrl,
17 } = options;
18
19 const response = await axios.post(
20 `${this.baseURL}/import`,
21 {
22 url,
23 includeVideo,
24 includeAudio,
25 videoQuality,
26 audioQuality,
27 webhookUrl,
28 },
29 {
30 headers: {
31 Authorization: `Bearer ${this.apiKey}`,
32 },
33 }
34 );
35
36 return response.data;
37 }
38
39 async getMetadata(url, webhookUrl = null) {
40 const params = { url };
41 if (webhookUrl) params.webhookUrl = webhookUrl;
42
43 const response = await axios.get(`${this.baseURL}/metadata`, {
44 params,
45 headers: {
46 Authorization: `Bearer ${this.apiKey}`,
47 },
48 });
49
50 return response.data;
51 }
52}
53
54export const importlyClient = new ImportlyClient(process.env.IMPORTLY_API_KEY);

3. Set Up Webhook Handler

Create an API route to handle webhook notifications:

javascript
1// pages/api/importly/webhook.js
2export default async function handler(req, res) {
3 if (req.method !== "POST") {
4 return res.status(405).json({ message: "Method not allowed" });
5 }
6
7 try {
8 const { type, data } = req.body;
9
10 switch (type) {
11 case "import.completed":
12 await handleImportCompleted(data);
13 break;
14 case "import.failed":
15 await handleImportFailed(data);
16 break;
17 case "metadata.completed":
18 await handleMetadataCompleted(data);
19 break;
20 default:
21 console.log("Unknown webhook type:", type);
22 }
23
24 res.status(200).json({ received: true });
25 } catch (error) {
26 console.error("Webhook error:", error);
27 res.status(500).json({ error: "Internal server error" });
28 }
29}
30
31async function handleImportCompleted(data) {
32 // Update your database, notify users, etc.
33 console.log("Import completed:", data);
34
35 // Example: Update database
36 // await db.imports.update({
37 // where: { id: data.jobId },
38 // data: {
39 // status: 'completed',
40 // mediaUrl: data.result.mediaUrl,
41 // creditsUsed: data.result.creditsUsed
42 // }
43 // })
44}
45
46async function handleImportFailed(data) {
47 console.log("Import failed:", data);
48 // Handle failure case
49}
50
51async function handleMetadataCompleted(data) {
52 console.log("Metadata completed:", data);
53 // Handle metadata completion
54}

4. Import Media in Your App

Create a component for importing media:

jsx
1// components/MediaImporter.jsx
2import { useState } from "react";
3import { importlyClient } from "../lib/importly";
4
5export default function MediaImporter() {
6 const [url, setUrl] = useState("");
7 const [importing, setImporting] = useState(false);
8 const [result, setResult] = useState(null);
9
10 const handleImport = async (e) => {
11 e.preventDefault();
12 setImporting(true);
13
14 try {
15 const response = await importlyClient.importMedia(url, {
16 videoQuality: "1080p",
17 webhookUrl: process.env.NEXT_PUBLIC_WEBHOOK_URL,
18 });
19
20 setResult(response);
21
22 // Store import ID for tracking
23 localStorage.setItem(
24 `import_${response.data.jobId}`,
25 JSON.stringify({
26 url,
27 timestamp: Date.now(),
28 status: "queued",
29 })
30 );
31 } catch (error) {
32 console.error("Import failed:", error);
33 } finally {
34 setImporting(false);
35 }
36 };
37
38 return (
39 <div className="max-w-md mx-auto p-6 bg-white rounded-lg shadow-md">
40 <h2 className="text-2xl font-bold mb-4">Import Media</h2>
41
42 <form onSubmit={handleImport} className="space-y-4">
43 <div>
44 <label
45 htmlFor="url"
46 className="block text-sm font-medium text-gray-700"
47 >
48 Media URL
49 </label>
50 <input
51 type="url"
52 id="url"
53 value={url}
54 onChange={(e) => setUrl(e.target.value)}
55 placeholder="https://example.com/video"
56 className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500"
57 required
58 />
59 </div>
60
61 <button
62 type="submit"
63 disabled={importing}
64 className="w-full bg-blue-600 text-white py-2 px-4 rounded-md hover:bg-blue-700 disabled:opacity-50"
65 >
66 {importing ? "Importing..." : "Import Media"}
67 </button>
68 </form>
69
70 {result && (
71 <div className="mt-4 p-4 bg-green-50 rounded-md">
72 <h3 className="text-sm font-medium text-green-800">Import Queued</h3>
73 <p className="mt-1 text-sm text-green-600">
74 Import ID: {result.data.jobId}
75 </p>
76 <p className="text-sm text-green-600">
77 You'll receive a webhook notification when complete.
78 </p>
79 </div>
80 )}
81 </div>
82 );
83}

5. Real-time Updates (Optional)

For real-time UI updates, you can use server-sent events or WebSocket connections:

javascript
1// pages/api/imports/[id]/status.js
2export default async function handler(req, res) {
3 const { id } = req.query;
4
5 // Check your database for import status
6 // const import = await db.imports.findUnique({ where: { id } })
7
8 res.status(200).json({
9 jobId: id,
10 status: "processing", // or 'completed', 'failed'
11 // ... other data
12 });
13}

Why Webhooks for Next.js?

Recommended Approach: Webhooks are ideal for Next.js because:

  • Server-side processing - Handle imports in API routes
  • No polling overhead - Efficient real-time updates
  • Scalable - Works with serverless functions
  • Reliable - Automatic retries and error handling
  • User experience - Instant notifications without constant checking

Best Practices

  1. Validate webhook signatures (implement webhook authentication)
  2. Store import status in your database for persistence
  3. Handle retries for failed webhook deliveries
  4. Use optimistic updates in your UI
  5. Implement proper error boundaries for better UX

Complete Example

Check out our complete Next.js example on GitHub for a full implementation with database integration and real-time updates.