Displaying files within a Lightning Web Component (LWC) can enhance your Salesforce application by enabling users to interact with documents, images, or attachments in a seamless, visually appealing way. Whether you’re working on a document management system, user profiles, or integration tracking, querying and displaying files can significantly improve user experience.
In this article, we’ll walk through how to query files stored in Salesforce and display them using a custom LWC component. We’ll cover key concepts like retrieving ContentDocument records, using Apex to expose this data, and finally designing an LWC that renders files attractively using Lightning Base Components or custom design.
1. Understanding How Files are Stored in Salesforce
Before diving into the code, it’s important to understand how files are managed within Salesforce’s data model. Salesforce uses the ContentDocument, ContentVersion, and ContentDocumentLink objects to store and manage files.
- ContentDocument: The primary record for a file that has been uploaded.
- ContentVersion: Represents a version of a document; the actual file is stored here.
- ContentDocumentLink: Links a ContentDocument to another object such as an Account, Case, or Custom Object.
Therefore, to retrieve files related to any record, we start with the ContentDocumentLink object to find file relationships and then get the latest version for download or display.
2. Writing the Apex Controller
Since LWC cannot directly perform complex SOQL queries involving multiple objects, we will use an Apex controller to fetch the files based on a given record ID.
public with sharing class FileController {
@AuraEnabled(cacheable=true)
public static List<ContentVersion> getFiles(Id recordId) {
List<ContentDocumentLink> links = [
SELECT ContentDocumentId
FROM ContentDocumentLink
WHERE LinkedEntityId = :recordId
];
List<Id> documentIds = new List<Id>();
for(ContentDocumentLink link : links) {
documentIds.add(link.ContentDocumentId);
}
return [
SELECT Title, ContentDocumentId, VersionData, FileExtension, Id
FROM ContentVersion
WHERE ContentDocumentId IN :documentIds
AND IsLatest = true
];
}
}
This controller method will allow us to call getFiles
from the LWC by passing the specific record ID and receiving a list of the latest file versions available for that record.
3. Creating the LWC Component
Next, we’ll create the actual LWC component that will call the Apex method and display each file dynamically.
The component will consist of three files:
- fileViewer.html – for layout
- fileViewer.js – for logic and data handling
- fileViewer.js-meta.xml – for metadata and exposure
fileViewer.html
<template>
<template if:true={files}>
<lightning-card title="Related Files" icon-name="standard:document">
<template for:each={files} for:item="file">
<div key={file.Id} class="slds-box slds-m-around_x-small">
<p><b>{file.Title}.{file.FileExtension}</b></p>
<lightning-button
label="View File"
onclick={handleFileClick}
data-id={file.ContentDocumentId}
class="slds-m-top_small">
</lightning-button>
</div>
</template>
</lightning-card>
</template>
<template if:true={error}>
<p class="slds-text-color_error">{error}</p>
</template>
</template>
fileViewer.js
import { LightningElement, api, wire } from 'lwc';
import getFiles from '@salesforce/apex/FileController.getFiles';
export default class FileViewer extends LightningElement {
@api recordId;
files;
error;
@wire(getFiles, { recordId: '$recordId' })
wiredFiles({ error, data }) {
if (data) {
this.files = data;
this.error = undefined;
} else if (error) {
this.error = error.body.message;
this.files = undefined;
}
}
handleFileClick(event) {
const docId = event.target.dataset.id;
window.open('/sfc/servlet.shepherd/document/download/' + docId, '_blank');
}
}
fileViewer.js-meta.xml
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>58.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__RecordPage</target>
</targets>
</LightningComponentBundle>
Now, you can place the fileViewer component on any record page using the Lightning App Builder and it will list all files related to that record. The user can view or download them with a simple click.
4. Display Enhancements and Previews
The example above provides functionality to download files, but what if you want to render previews like images or PDFs inline? That’s possible too!
Depending on the file type, you can use the ContentVersion’s VersionData
or embed the file using an <iframe>
or <img>
tag.
<template for:each={files} for:item="file">
<div key={file.Id} class="slds-box slds-m-around_x-small">
<p><b>{file.Title}</b></p>
<template if:true={isImage(file.FileExtension)}>
<img src={'/sfc/servlet.shepherd/version/download/' + file.Id} alt="file image" style="max-width: 100%;" />
</template>
</div>
</template>
Here, you’ll need to add a helper method in your JavaScript to check whether the file is an image.
isImage(fileExt) {
return ['jpg', 'jpeg', 'png', 'gif'].includes(fileExt.toLowerCase());
}

5. Security and Access Considerations
Every time you work with file data, especially in a multi-user environment like Salesforce, it’s important to consider access rights. Your Apex controller should run in sharing mode to respect record-level access rules unless you have specific reasons not to.
Also, be careful with exposing file download URLs. While the standard URL constructs from Salesforce work, they shouldn’t be sent to unauthorized users. Use Apex sharing and field-level security best practices while querying and exposing properties like VersionData
.
6. Use Cases and Customization Ideas
This component opens the door to many possible real-world uses. Here are some ideas to inspire you:
- User Profile Pictures: Show user-uploaded avatars on user or contact pages.
- Proposal Attachments: Make attached PDFs viewable from the opportunity record.
- Case Attachments: Automatically preview screenshots or documents submitted via support cases.

Conclusion
Adding file display capabilities to your LWC not only enhances user experience but also streamlines access to important documents and resources. By understanding how Salesforce stores files and using a mix of Apex and LWC, you can create sleek, practical file viewers.
Whether you’re building internal tools or customer-facing portals, querying and displaying ContentDocuments can dramatically improve usability. With just a few lines of well-structured code, your Lightning components can become powerful document management utilities.
Use this