Contributing Providers
Contributing New Providers
Want to add support for OneDrive, Dropbox, S3, or another file storage service? This guide will walk you through the process!
Overview
Adding a new provider involves three main steps:
- Add the provider type to the TypeScript definitions
- Create the transformation logic in the composable
- Add a server route (if needed for CORS/authentication)
Step 1: Add Provider Type
Edit src/runtime/types.ts to add your new provider:
// Before
export type PdfProvider = "url" | "gdrive" | "custom";
// After
export type PdfProvider = "url" | "gdrive" | "onedrive" | "custom";
Step 2: Add Transformation Logic
Edit src/runtime/composables/usePdfKitProvider.ts:
/**
* Transform OneDrive share link to direct download URL
*/
function transformOneDrive(src: string, config?: ProviderConfig): string {
// Clean the share ID
const shareId = src.trim();
// Get proxy route from config or use default
const proxyRoute = config?.baseUrl || "/pdf-proxy/onedrive";
return `${proxyRoute}/${shareId}.pdf`;
}
// Add to the main function
export function usePdfKitProvider(
provider: PdfProvider = "url",
src: string,
config?: ProviderConfig,
): string {
if (!src) {
console.warn("[nuxt-pdf-kit] Empty src provided to usePdfKitProvider");
return "";
}
switch (provider) {
case "gdrive":
return transformGoogleDrive(src, config);
case "onedrive": // Add this
return transformOneDrive(src, config);
case "custom":
return transformCustom(src, config);
case "url":
default:
return src;
}
}
Step 3: Create Server Route (Optional)
If your provider needs CORS handling or authentication, create a server route:
Create the route file
src/runtime/server/routes/pdf-proxy/onedrive/[id].ts:
import {
createError,
defineEventHandler,
sendStream,
setResponseHeader,
} from "h3";
export default defineEventHandler(async (event) => {
// 1. Extract file ID from URL
const path = event.path || event.node.req.url || "";
const match = path.match(/\/pdf-proxy\/onedrive\/([^/]+?)(?:\.pdf)?$/);
const shareId = match ? match[1] : "";
if (!shareId) {
throw createError({
statusCode: 400,
statusMessage: "OneDrive share ID is missing",
});
}
// 2. Construct OneDrive download URL
// Example: Convert share link to direct download
const oneDriveUrl = `https://api.onedrive.com/v1.0/shares/${shareId}/root/content`;
try {
// 3. Fetch from OneDrive
const response = await fetch(oneDriveUrl, {
headers: {
"User-Agent": "Mozilla/5.0...",
Accept: "*/*",
},
redirect: "follow",
});
if (!response.ok) {
throw createError({
statusCode: response.status,
statusMessage: `OneDrive Error: ${response.statusText}`,
});
}
// 4. Check Content-Type
const contentType = response.headers.get("content-type");
if (contentType && !contentType.includes("application/pdf")) {
throw createError({
statusCode: 502,
statusMessage: "OneDrive did not return a PDF file",
});
}
// 5. Set response headers
setResponseHeader(event, "Content-Type", "application/pdf");
setResponseHeader(event, "Cache-Control", "public, max-age=86400");
setResponseHeader(event, "Access-Control-Allow-Origin", "*");
// 6. Stream the response
if (!response.body) {
throw createError({
statusCode: 500,
statusMessage: "Empty response from OneDrive",
});
}
return sendStream(event, response.body);
} catch (error: any) {
console.error("[nuxt-pdf-kit] OneDrive error:", error.message);
if (error.statusCode) {
throw error;
}
throw createError({
statusCode: 500,
statusMessage: error.message || "Internal Server Error",
});
}
});
Register the route
Edit src/module.ts to register your server route:
// Add server routes for providers
nuxt.hook("nitro:config", (nitroConfig) => {
nitroConfig.handlers = nitroConfig.handlers || [];
// Google Drive proxy route
nitroConfig.handlers.push({
route: "/pdf-proxy/gdrive/**",
handler: resolver.resolve("./runtime/server/routes/pdf-proxy/gdrive/[id]"),
});
// OneDrive proxy route (ADD THIS)
nitroConfig.handlers.push({
route: "/pdf-proxy/onedrive/**",
handler: resolver.resolve(
"./runtime/server/routes/pdf-proxy/onedrive/[id]",
),
});
});
Step 4: Add Tests
Create a test file test/providers.test.ts:
import { describe, it, expect } from "vitest";
import { usePdfKitProvider } from "../src/runtime/composables/usePdfKitProvider";
describe("usePdfKitProvider", () => {
it("transforms OneDrive share ID correctly", () => {
const result = usePdfKitProvider(
"onedrive",
"u!aHR0cHM6Ly8xZHJ2Lm1zL2IvcyFBcXRhYmNkZWY",
);
expect(result).toBe(
"/pdf-proxy/onedrive/u!aHR0cHM6Ly8xZHJ2Lm1zL2IvcyFBcXRhYmNkZWY.pdf",
);
});
it("uses custom baseUrl for OneDrive", () => {
const result = usePdfKitProvider("onedrive", "share-123", {
baseUrl: "/custom-proxy",
});
expect(result).toBe("/custom-proxy/share-123.pdf");
});
});
Step 5: Add Documentation
Create documentation for your provider in docs/content/en/5.advanced/2.providers.md:
### OneDrive Provider
Load PDFs from OneDrive share links.
\`\`\`vue
<template>
<NuxtPdfKit
provider="onedrive"
src="u!aHR0cHM6Ly8xZHJ2Lm1zL2IvcyFBcXRhYmNkZWY"
/>
</template>
\`\`\`
**How to get OneDrive Share ID:**
1. Right-click your file in OneDrive
2. Click "Share" → "Copy link"
3. Extract the share ID from the URL
4. Use that ID as the `src` prop
Step 6: Submit Pull Request
- Fork the repository on GitHub
- Create a feature branch:
git checkout -b feat/onedrive-provider - Commit your changes:
git commit -m "feat: add OneDrive provider support" - Push to your fork:
git push origin feat/onedrive-provider - Open a Pull Request with:
- Clear description of the provider
- Usage examples
- Any limitations or known issues
Provider Checklist
Before submitting your PR, make sure:
- Provider type added to
types.ts - Transformation logic added to
usePdfKitProvider.ts - Server route created (if needed)
- Server route registered in
module.ts - Tests added and passing
- Documentation added
- Example usage in playground
- TypeScript types are correct
- No lint errors
Best Practices
Error Handling
Always provide clear error messages:
if (!fileId) {
throw createError({
statusCode: 400,
statusMessage: "File ID is missing. Please provide a valid share link.",
});
}
Logging
Use consistent logging format:
console.log("[nuxt-pdf-kit] OneDrive - Processing file:", fileId);
console.error("[nuxt-pdf-kit] OneDrive error:", error.message);
Caching
Set appropriate cache headers:
// Cache for 24 hours
setResponseHeader(event, "Cache-Control", "public, max-age=86400");
// Or disable caching for sensitive files
setResponseHeader(
event,
"Cache-Control",
"no-cache, no-store, must-revalidate",
);
Security
- Never expose API keys or secrets in client-side code
- Validate all user inputs
- Use HTTPS for all external requests
- Set appropriate CORS headers
Need Help?
- Discord: Join our community server
- GitHub Issues: Open an issue for questions
- Email: [email protected]
We're excited to see what providers you'll add! 🚀