How to show Classic knowledge articles in Salesforce Lightning

When migrating from Salesforce Classic to Salesforce Lightning, it’s also recommended to activate Lightning Knowledge. Classic knowledge articles are technically still available to users in Lightning. But, it’s more difficult to surface them in Lightning apps and pages. There are many benefits to activating Lightning Knowledge. However, depending on your structure and dependencies, migration could take some time.

This article shows a work around. Use a Lightning web component to bring classic knowledge article search to users on Lightning. The component has a search text input and shows matching articles.

<template>
    
    <!-- Search -->
    <div class="slds-form-element">
        <label class="slds-form-element__label" for="knowledge-input-id">Search</label>
        <div  class="slds-form-element__control slds-input-has-icon slds-input-has-icon_left">
            <svg class="slds-icon slds-input__icon slds-input__icon_left slds-icon-text-default" aria-hidden="true">
                <use xlink:href="/_slds/icons/utility-sprite/svg/symbols.svg#search"></use>
            </svg>
            <input type="text" id="knowledge-input-id" placeholder="Type to search" class="slds-input" onkeyup={handleInput}/>
        </div>
    </div>
    
    <!-- Results -->
    <template if:true={articles}>
        <div>
            <ul class="slds-has-dividers_around-space">
                <li for:each={articles} for:item="article" key={article.KnowledgeArticleId} class="slds-item">
                    <article class="slds-tile slds-media">
                        <!-- Article Icon -->
                        <div class="slds-media__figure">
                            <span class="slds-icon_container" title="description of icon when needed">
                                <svg class="slds-icon slds-icon-standard-article" aria-hidden="true">
                                    <use xlink:href="/_slds/icons/standard-sprite/svg/symbols.svg#article"></use>
                                </svg>
                            </span>
                        </div>
                        <!-- Article Info -->
                        <div class="slds-media__body">
                            <h3 class="slds-truncate" title={article.Title}>
                                <a onclick={handleClick} name={article.KnowledgeArticleId}>{article.Title}</a>
                            </h3>
                            <div class="slds-tile__detail slds-truncate">
                                {article.Summary}
                            </div>
                        </div>
                    </article>
                </li>
            </ul>
        </div>
    </template>
        
</template>

You will need a helper Apex class that runs the query for articles. By querying the KnowledgeArticleVersion object, you can query across different Knowledge article objects you may have set up. For demonstration purposes, this example is pretty simple. There is an opportunity here to make search more sophisticated (i.e. search term manipulation, adding more query conditions, …).

There is also a helper method to determine the object name from a record Id. This comes in handy when you have multiple knowledge article objects. It is used later when redirecting to an article page from a search result.

public class KnowledgeUtility {
    
    /* query knowledge articles */
    @AuraEnabled(cacheable=true)
    public static List<KnowledgeArticleVersion> getArticles(String searchTerm){
        //don't search if the search term is blank
        if(searchTerm == null || searchTerm == ''){ return null;}
        // add wildcards
        searchTerm = \'%'+searchTerm+'%\';
        // query
        return [SELECT Id, Title, Summar, KnowledgeArticleId
            FROM KnowledgeArticleVersion
            WHERE PublishStatus='Online'
            AND (Title LIKE :searchTerm OR Summary LIKE :searchTerm)
        ];
    }
    
    /* get the object name from a record id */
    @AuraEnabled
    public static String objectNameFromId(Id recordId){
        return recordId.getSObjectType().getDescribe().getName();
    }
}

The Lightning web component javascript has two methods: One kicks off the article search and one opens the article page when a user clicks a search result. This is using NavigationMixin with which you can open a Salesforce record in a new Lightning tab. When implementing this work around component, it’s a good call to check on page layouts for each of your knowledge article objects to ensure users see relevant information.

import {LightningElement, track} from 'lwc';
import getArticles from '@salesforce/apex/KnowledgeUtility.getArticles';
import getObjectName from '@salesforce/apex/KnowledgeUtility.objectNameFromId';
import { NavigationMixin } from 'lightning/navigation';

export default class Lightningknowledge extends NavigationMixin(LightningElement) {
    
    // search term
    searchTerm = '';
    // articles returned from query
    articles;
    
    // typing in the search box kicks off article search when more than 3 characters entered
    handleInput(event){
        let input = event.target.value;

        if(input.length > 3){
            this.searchTerm = input;
            getArticles({searchTerm: this.searchTerm})
            .then((result)=>{
                this.articles = result;
            })
            .catch(error => {
                throw error; 
            });
        }
    }
    
    // clicking on a knowledge article title open the article sfdc record in a new tab
    handleClick(event) {
        // extract the article id and determine which knowledge article object it is
        let articleId = event.target.name
        
        getObjectName({recordId: articleId})
        .then((objName)=>{
            // then open that object record page with the article id
            this[NavigationMixin.Navigate]({
                type: 'standard__recordPage',
                attributes: {
                    recordId: articleId,
                    objectApiName: objName,
                    actionName: 'view',
                },
            });
        })
        .catch(error => {
            throw error; 
        });
        
    }
    
}

Want to read more blog entries about Salesforce development? Follow me.