Skip to content


The Slicknode Cloud comes with a highly scalable and secure module to store large files. The file module integrates fully with the authorization functionality of Slicknode which lets you define the users that have access to uploaded files.

Files can also be public and be served via a global CDN for minimum latency.


The file module can be installed as any module in slicknode. In your project folder run:

slicknode module add file

This will add the module to your slicknode.yml file of the project. Afterwards deploy the changes to the cloud:

slicknode deploy


Once the file module is installed and deployed, the File type is available in your GraphQL schema and can be used as any other type for fields in your data structure.


Let's say we have a comment module in a blog application where we want to allow the users to attach files to comments. Just define the field in your schema.graphql file:

type Blog_Comment implements Node {
  id: ID!
  text: String!
  attachment: File

File objects are supposed to be attached to other nodes. The File object itself is just a reference to the actual file in the file storage. It is used to generate the URL to the file and stores meta data like the file size, Mime-Type etc. of the object.


The file upload with the file module is a two step process:

  1. Create a File node in the system with the createFile mutation. This saves a reference to the file in the database and returns a temporary uploadUrl. At this point the actual file is not yet uploaded.
  2. Use the uploadUrl that was obtained in the previous step to upload the file with a PUT request. This uploads the file directly to the storage backend to reduce the resource usage on your API server.


import Client from 'slicknode-client';
import 'isomorphic-fetch';

const client = new Client({
  endpoint: '<my-slicknode-endpoint>'

// ... authenticate user

const mutation = `mutation CreateFile {
  createFile(input: {
    # The file is publicly accessible
    isPublic: true, 

    # The filename as it will be stored on the server
    name: "filename.pdf", 

    # The mimetype of the file, also set in the Content-Type header
    mimeType: "application/pdf"
  }) {
    # This the temporary URL where the file can be uploaded
    file {
      # The URL to the file, once it is uploaded

      # Temporary token needed to attach the file to other nodes

// Run mutation
  .then(({data}) => {
    const payload = data.createFile;

    // Now we can upload the file
    console.log('Success, upload file to: ', payload.uploadUrl);

    // Temporary token that is needed to attach the file to other nodes
    const token = payload.file.token;

    // Get the reference to your file from your input element, dropzone component etc.
    // For simplicity, we are just assuming we have a DOM element with a selected file. 
    const file = document.getElementById('#file-input').files[0];
    // Run file upload
    fetch(payload.uploadUrl, {
      method: 'PUT',
      headers: {
        'Content-Length': file.length,
        'Content-Type': file.type
      body: file
      .then(() => {
        console.log('Fileupload successful');
      .catch(err => {
        console.log(`Fileupload to data store failed: ${err.message}`);
  .catch(err => {
    console.log('Error creating file: ' + err.message);

Attaching Files to Nodes

To attach files to other nodes, you have to pass the temporary token of a file to one of the mutations. The token can be obtained directly when the file is first created with the createFile mutation (see example above), or you can also use a token of a File that is already stored in your system. This lets you reuse files for multiple nodes, for example if you want to build a media library and reuse the same asset with multiple nodes.


For the schema as defined under definition the mutation to create a new comment with an attachment that was previously uploaded as described in the upload section could look something like this:

mutation CreateComment {
  Blog_createComment(input: {
    text: "Test comment with attachment",

    # Pass the file token of the file that shuold be attached to the comment
    attachment: "<file-token>"
  }) {
    node {
      attachment {
        # URL to the file