Copy & move SharePoint documents/folders using PnPjs

The latest release of PnPjs contains 4 new methods. They allow you to copy and move, files and folders, to a different folder on the same or a different site collection. And they are incredibly fast!

Motivation

I have been recently asked by a client to develop a feature replacement to the default SharePoint copy and move to features. The OOB versions had some limitations that were causing problems to end users. With this in mind, I started by creating a proof-of-concept solution (SPFx list view command set extension). But soon realized that the functionality to copy and move files/folders between sites was not available in PnPjs. And so I added it and submitted a pull request (my first ever for the main PnPjs repository)!

Update: I wrote a blog post providing more details about the copy and move extension. You can read more here.

New copy and move features

  • Copy and move documents and folders to the same site. PnPjs already had methods to do this, but using a different API endpoint
  • Copy and move documents and folders to a different site
  • If a file with the same name already exists, you can decide to replace or keep both. When keeping both files, a numeric value will by added to the name of the new file
  • If a folder with the same name already exists when moving, you can decide to keep both.  When keeping both folders, a numeric value will by added to the name of the new folder. The replace option is not available for folders
  • Copying will not persist the version history of the source file
  • Moving will persist the version history of the source file

Usage

As part of the pull request to add the new capabilities I have also updated the documentation (and tests) so people can easily understand how to use them. In short, your code will look similar to this (or use promises if you prefer):

Copy file by path
await sp.web.getFileByServerRelativePath(srcPath).copyByPath(`${destPath}/${name}`, shouldOverWrite, KeepBoth);
Move file by path
await sp.web.getFileByServerRelativePath(srcPath).moveByPath(`${destPath}/${name}`, shouldOverWrite, KeepBoth);
Copy folder by path
await sp.web.getFolderByServerRelativePath(srcPath).copyByPath(`${destPath}/${name}`, keepBoth);
Move folder by path
await sp.web.getFolderByServerRelativePath(srcPath).moveByPath(`${destPath}/${name}`, keepBoth);

Extra: Contributing to PnPjs

I use PnPjs for a very long time as it immensely helps me on my daily job, so I’m very happy that I was able to add a little bit more to it.

The project is so big that the first feeling I had was that adding the code there would take me longer than doing it on my own solution – but it clearly was the right thing to do. But guess what? The code is so well structured that this is actually pretty simple! All I had to do was to find the file where my functions should go (just follow the logical structure of folders that mirror the different packages) and find a similar function that I used as a starting point. Update the reference to the target REST API endpoint, update the data passed in the body (for POST requests) and all was done! All that was left to do after that was to update the documentation and tests, where I followed a similar approach.

We can all use it on any project going forward without having to worry about it! Sharing is caring 🙂

3 thoughts on “Copy & move SharePoint documents/folders using PnPjs

  1. Hi, when I try to use .copyByPath() I get this System.UriFormatException “Invalid URI: The format of the URI could not be determined.”.
    I tried it with both absolute and relative urls. On one and on two different site collections. Getting the File with .getFileByServerRelativePath() seems to be working.
    Any idea how I can fix this? Thanks!

    1. Hi Moritz, any chance you can share a sample request? Please don’t include sensitive information
      You can also check the request url on the network tab of the browser dev tools and validate if the destination path is correct and a file name is provided. For example: /sites/mysite/mylibrary/testfile.pdf

Leave a Reply