Apollo GraphQL File Upload Link
apollo-upload-client is a terminating Apollo Link for Apollo Client that facilitates file uploads within GraphQL mutations using the GraphQL multipart request specification. It automatically detects `FileList`, `File`, or `Blob` instances in GraphQL variables and constructs a multipart request, falling back to a standard GraphQL POST or GET request otherwise. The current stable version is 19.0.0, with major versions released somewhat frequently to align with `@apollo/client` updates and Node.js LTS changes. Its primary differentiator is seamless integration with Apollo Client for file uploads, abstracting the multipart request complexity, and adhering to the community-standard GraphQL multipart request specification. It requires a compatible server-side implementation that also follows the specification.
Common errors
-
Error: Cannot find module '@apollo/client'
cause Missing `@apollo/client` peer dependency, especially after v15.0.0.fixRun `npm install @apollo/client` or `yarn add @apollo/client`. -
TypeError: Cannot read properties of undefined (reading 'files') or related file upload issues.
cause The GraphQL server does not implement the GraphQL multipart request specification, or the resolvers are not configured to handle file uploads.fixEnsure your GraphQL server is compatible with the `graphql-multipart-request-spec` and that your resolvers are correctly processing the `Upload` scalar. -
Error: Link is not a function or related Apollo Link initialization errors.
cause Incorrect import or instantiation of `createUploadLink`, or using an incompatible version of `@apollo/client`.fixVerify that you are using `import { createUploadLink } from 'apollo-upload-client';` and that your `@apollo/client` version matches the peer dependency requirements. -
SyntaxError: Named export 'createUploadLink' not found. The requested module 'apollo-upload-client' does not provide an export named 'createUploadLink'
cause Attempting to `require` an ESM-only package or incorrect module resolution setup for Node.js.fixEnsure your project uses ES modules (`import`/`export`) or is transpiled correctly. For Node.js, confirm `type: module` in `package.json` or use `.mjs` files.
Warnings
- breaking Node.js support has been tightened. Version 19.0.0 requires `^20.9.0 || >=22.0.0`. Older versions required different Node.js ranges.
- breaking The `@apollo/client` peer dependency was updated to `^4.0.0` in v19.0.0 and `^3.8.0` in v18.0.0. Mismatching versions can lead to runtime errors or unexpected behavior.
- breaking React Native is no longer supported out of the box since v18.0.0. The `ReactNativeFile` class is no longer exported or matched by `isExtractableFile`.
- breaking A new peer dependency `rxjs` at `^7.3.0` was added in v19.0.0, as it is a requirement for `@apollo/client` v4.
- breaking The package moved from `@apollo/client` as a direct dependency to a peer dependency in v15.0.0. This change requires developers to explicitly install `@apollo/client` themselves.
- gotcha This library is a 'terminating link'. Apollo Client can only have one terminating link. If you're already using `HttpLink`, you must replace it with `createUploadLink`.
Install
-
npm install apollo-upload-client -
yarn add apollo-upload-client -
pnpm add apollo-upload-client
Imports
- createUploadLink
const createUploadLink = require('apollo-upload-client').createUploadLink;import { createUploadLink } from 'apollo-upload-client'; - UploadHttpLink
import UploadHttpLink from 'apollo-upload-client/UploadHttpLink';
import { UploadHttpLink } from 'apollo-upload-client'; - ApolloClient
import { ApolloClient, InMemoryCache } from '@apollo/client';
Quickstart
import { ApolloClient, InMemoryCache, gql, ApolloProvider } from '@apollo/client';
import { createUploadLink } from 'apollo-upload-client';
import React from 'react';
import { useMutation } from '@apollo/client/react';
// Configure the Apollo Client with the upload link
const uploadLink = createUploadLink({
uri: 'http://localhost:4000/graphql', // Replace with your GraphQL server endpoint
});
const client = new ApolloClient({
cache: new InMemoryCache(),
link: uploadLink,
});
// GraphQL mutation definition for file upload
const UPLOAD_FILE_MUTATION = gql`
mutation uploadFile($file: Upload!) {
uploadFile(file: $file) {
filename
mimetype
encoding
success
}
}
`;
/** React component for uploading a single file. */
function UploadFileComponent() {
const [uploadFile, { loading, error, data }] = useMutation(UPLOAD_FILE_MUTATION);
const handleFileChange = ({ target: { validity, files } }) => {
if (validity.valid && files && files[0]) {
uploadFile({
variables: {
file: files[0],
},
});
}
};
return (
<div>
<input type="file" required onChange={handleFileChange} />
{loading && <p>Uploading...</p>}
{error && <p>Error: {error.message}</p>}
{data && <p>Upload successful: {data.uploadFile.filename}</p>}
</div>
);
}
// Root component to provide Apollo Client context
function App() {
return (
<ApolloProvider client={client}>
<h1>File Upload Example</h1>
<UploadFileComponent />
</ApolloProvider>
);
}
export default App;