Skip to content

Previewing Photoshop File Content in a NuxtJS App

Working with PSD files can be complex as they are not natively supported by HTML. However, it is a widely used format globally by creators and professionals in various fields. Let us learn how we can preview the photoshop file and its content for our users.

The final project can be viewed on Codesandbox.

You can find the full source code on my Github repository.

Nuxt.Js is a performant Vue.Js framework that boosts developer experience and productivity. To get started ensure you have yarn or npm v5.2+/v6.1+ installed. Open your terminal in your preferred working directory.

yarn create nuxt-app nuxtjs-photoshop-preview

npx create-nuxt-app nuxtjs-photoshop-preview

npm init nuxt-app nuxtjs-photoshop-preview

This will trigger a set of setup questions. Here are our recommended defaults:

Project name: nuxtjs-photoshop-preview Programming language: JavaScript Package manager: Yarn UI framework: Tailwind CSS Nuxt.js modules: N/A Linting tools: N/A Testing frameworks: None Rendering mode: Universal (SSR/SSG) Deployment target: Server (Node.js hosting) Development tools: N/A What is your Github username? < your-github-username > Version control system: Git

Once the setup and customization are complete you may enter the directory and run the project.

cd nuxtjs-photoshop-preview

yarn dev
# OR
npm run dev
Code language: PHP (php)

You should now be able to view your project on http://localhost:3000.

Cloudinary enables us to make the most of our media assets through its set of APIs and SDKs. Let us install the recommended Nuxt.Js plugin, @nuxtjs/cloudinary.

yarn add @nuxtjs/cloudinary
# or
npm install @nuxtjs/cloudinary
Code language: CSS (css)

Once installation is complete, add the module in the modules section of the nuxt.config.js file:

// nuxt.config.js
export default {
    ...
    modules: [
        '@nuxtjs/cloudinary'
    ]
    ...
}
Code language: JavaScript (javascript)

We will then configure our Cloudinary instance by adding a cloudinary section to the nuxt.config.js file:

// nuxt.config.js
export default {
    ...
    cloudinary: {
        cloudName: process.env.NUXT_ENV_CLOUDINARY_CLOUD_NAME,
        useComponent: true,
        secure: true
    }
    }
Code language: JavaScript (javascript)

We refer to an environmental variable (NUXT_ENV_CLOUDINARY_CLOUD_NAME). Environmental variables are values we do not want in our codebase for either customization or security reasons. Let us first create the .env file which will contain our environmental variables:

touch .env
Code language: CSS (css)

We will then set our environmental variables in the file

NUXT_ENV_CLOUDINARY_CLOUD_NAME=<secret-cloud-name>
Code language: HTML, XML (xml)

Before we preview the photoshop file, we need to upload it to Cloudinary. Let us create a form to do this.

<!-- pages/index.vue -->
<template>
    ...
      <form @submit.prevent="upload">
        <div>
          <label for="psd" >
            Photoshop file
          </label>
          <div class="mt-1">
            <input 
                @change="handleFile" 
                id="psd" 
                name="psd" 
                type="file" 
                accept=".psd" 
                required 
            />
          </div>
        </div>

        <div>
          <p v-if="uploading">Uploading... </p>
          <button v-else type="submit">
            Upload
          </button>
        </div>
      </form>
    ...
</template>
Code language: HTML, XML (xml)

The handleFile method, triggered when a file is selected, will save the selection in the page state.

// pages/index.vue
<script>
export default {
  data() {
    return {
      file: null,
    };
  },
  methods: {
    async handleFile(e) {
      this.file = e.target.files[0];
    },
  },
};
</script>
Code language: HTML, XML (xml)

When the file is submitted we trigger the submit method which uploads the file to Cloudinary. It makes use of the readData method used to read the file contents and return them for upload.

// pages/index.vue
<script>
export default {
  name: 'IndexPage',
  data(){
    return {
        ...
        uploading:false,
        cloudinaryFile:null,
    };
  },
  methods:{
    ...
    async readData(f) {
      return new Promise((resolve) => {
        const reader = new FileReader();
        reader.onloadend = () => resolve(reader.result);
        reader.readAsDataURL(f);
      });
    },
    async upload() {
      this.uploading = true;
      const fileData = await this.readData(this.file);
      this.cloudinaryFile = await this.$cloudinary.upload(fileData, {
        upload_preset: "default-preset",
        folder: "nuxtjs-photoshop-preview",
      });
      this.uploading = false;
      this.getLayers();
    }
  }
}
</script>

Code language: HTML, XML (xml)

The above code snippet refers to the default-preset upload preset. Upload presets are a pre-configured set of options that will be applied to our uploads. They are required for client-side unsecured uploads. To create an upload preset proceed to add upload preset page. We recommend using the following settings.

Name: default-preset Mode: unsigned Unique filename: true Delivery type: upload Access mode: public

As visible in the above code snippet, once the upload is complete, a getLayers. This is the method we use to get the layers from the photoshop file as images. We do this by accessing pages of the image until there are no other pages to show. We then add all the pages into an images array as they are images of different layers.

// pages/index.vue
<script>
export default {
  name: 'IndexPage',
  data(){
    return {
      ...
      images:[]
    };
  },
  methods:{
    ...
    async getLayers(){
      this.images = [];
      let count = 0;
      let resp;
      do{
        count++;
        let url =  this.$cloudinary.image.url(
          `${this.cloudinaryFile.public_id}.jpg`,
          {page:count}
        );
        resp = await fetch(url);
        if(resp.ok){
          this.images.push(url);
        }
      }while(resp.ok);
      console.log(this.images);
    }
  }
}
</script>
Code language: HTML, XML (xml)

Once all the layers are in the images array, we can now iterate the array and display them in our user interface.

<!-- pages/index.vue -->
<template>
  ...
  <div>
    <div v-for="image in images" :key="image" >
      <img :src="image" class="m-auto" />
    </div>
  </div>
  ...
</template>
Code language: HTML, XML (xml)

Through this project, we are now able to upload and preview all the layers of a photoshop file. To read more about what we can do with photoshop files, feel free to read the documentation on delivering photoshop images.

Back to top

Featured Post