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.
Codesandbox
The final project can be viewed on Codesandbox.
You can find the full source code on my Github repository.
Nuxt.Js App Setup
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.
1yarn create nuxt-app nuxtjs-photoshop-preview23npx create-nuxt-app nuxtjs-photoshop-preview45npm 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.
1cd nuxtjs-photoshop-preview23yarn dev4# OR5npm run dev
You should now be able to view your project on http://localhost:3000.
@nuxtjs/cloudinary installation
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.
1yarn add @nuxtjs/cloudinary2# or3npm install @nuxtjs/cloudinary
Once installation is complete, add the module in the modules
section of the nuxt.config.js
file:
1// nuxt.config.js2export default {3 ...4 modules: [5 '@nuxtjs/cloudinary'6 ]7 ...8}
We will then configure our Cloudinary instance by adding a cloudinary
section to the nuxt.config.js
file:
1// nuxt.config.js2export default {3 ...4 cloudinary: {5 cloudName: process.env.NUXT_ENV_CLOUDINARY_CLOUD_NAME,6 useComponent: true,7 secure: true8 }9 }
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:
1touch .env
We will then set our environmental variables in the file
1NUXT_ENV_CLOUDINARY_CLOUD_NAME=<secret-cloud-name>
Uploading photoshop files to Cloudinary
Before we preview the photoshop file, we need to upload it to Cloudinary. Let us create a form to do this.
1<!-- pages/index.vue -->2<template>3 ...4 <form @submit.prevent="upload">5 <div>6 <label for="psd" >7 Photoshop file8 </label>9 <div class="mt-1">10 <input11 @change="handleFile"12 id="psd"13 name="psd"14 type="file"15 accept=".psd"16 required17 />18 </div>19 </div>2021 <div>22 <p v-if="uploading">Uploading... </p>23 <button v-else type="submit">24 Upload25 </button>26 </div>27 </form>28 ...29</template>
The handleFile
method, triggered when a file is selected, will save the selection in the page state.
1// pages/index.vue2<script>3export default {4 data() {5 return {6 file: null,7 };8 },9 methods: {10 async handleFile(e) {11 this.file = e.target.files[0];12 },13 },14};15</script>
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.
1// pages/index.vue2<script>3export default {4 name: 'IndexPage',5 data(){6 return {7 ...8 uploading:false,9 cloudinaryFile:null,10 };11 },12 methods:{13 ...14 async readData(f) {15 return new Promise((resolve) => {16 const reader = new FileReader();17 reader.onloadend = () => resolve(reader.result);18 reader.readAsDataURL(f);19 });20 },21 async upload() {22 this.uploading = true;23 const fileData = await this.readData(this.file);24 this.cloudinaryFile = await this.$cloudinary.upload(fileData, {25 upload_preset: "default-preset",26 folder: "nuxtjs-photoshop-preview",27 });28 this.uploading = false;29 this.getLayers();30 }31 }32}33</script>
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
Getting the photoshop file layers
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.
1// pages/index.vue2<script>3export default {4 name: 'IndexPage',5 data(){6 return {7 ...8 images:[]9 };10 },11 methods:{12 ...13 async getLayers(){14 this.images = [];15 let count = 0;16 let resp;17 do{18 count++;19 let url = this.$cloudinary.image.url(20 `${this.cloudinaryFile.public_id}.jpg`,21 {page:count}22 );23 resp = await fetch(url);24 if(resp.ok){25 this.images.push(url);26 }27 }while(resp.ok);28 console.log(this.images);29 }30 }31}32</script>
Displaying the photoshop file layers
Once all the layers are in the images
array, we can now iterate the array and display them in our user interface.
1<!-- pages/index.vue -->2<template>3 ...4 <div>5 <div v-for="image in images" :key="image" >6 <img :src="image" class="m-auto" />7 </div>8 </div>9 ...10</template>
Conclusion
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.