<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>post Using GitHub Copilot To Build Service Portal Widgets in Developer articles</title>
    <link>https://www.servicenow.com/community/developer-articles/using-github-copilot-to-build-service-portal-widgets/ta-p/2976541</link>
    <description>&lt;ARTICLE class="nx-container nx-prose max-md:nx-prose-sm dark:nx-prose-dark" dir="ltr"&gt;
&lt;DIV class="nx-mb-8 nx-flex nx-gap-3 nx-items-center"&gt;
&lt;DIV class="nx-flex nx-items-center nx-gap-3 print:nx-hidden"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;P&gt;Developing custom ServiceNow Service Portal widgets will enhance the UI and UX of your Portal, including GitHub Copilot while developing can streamline the process significantly. This post will delve into best practices for writing ServiceNow Service Portal widget code.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H2 class="nx-not-prose subheading-h2"&gt;TLDR&lt;A id="tldr" class="subheading-anchor" href="#tldr" target="_blank" rel="noopener" aria-label="Permalink for this section"&gt;&lt;/A&gt;&lt;/H2&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Ghost text, in particular, plays a crucial role by providing context-aware suggestions and allowing real-time editing. Knowing the capabilities of AngularJS directives will aid in provide in suggestions. Have your files open in your IDE will give you more suggestions.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H2 class="nx-not-prose subheading-h2"&gt;Assumptions before you read this&lt;A id="assumptions-before-you-read-this" class="subheading-anchor" href="#assumptions-before-you-read-this" target="_blank" rel="noopener" aria-label="Permalink for this section"&gt;&lt;/A&gt;&lt;/H2&gt;
&lt;UL&gt;
&lt;LI&gt;You know about &lt;A href="https://www.servicenow.com" target="_blank" rel="noopener noreferrer"&gt;ServiceNow&lt;SPAN class="nx-sr-only nx-select-none"&gt; (opens in a new tab)&lt;/SPAN&gt;&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;You have built a &lt;A href="https://docs.servicenow.com/bundle/washingtondc-platform-user-interface/page/build/service-portal/concept/adv-widget-tutorial.html" target="_blank" rel="noopener noreferrer"&gt;Custom ServiceNow Service Portal Widget&lt;SPAN class="nx-sr-only nx-select-none"&gt; (opens in a new tab)&lt;/SPAN&gt;&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;You have &lt;A href="https://github.com/features/copilot" target="_blank" rel="noopener noreferrer"&gt;Github Copilot&lt;SPAN class="nx-sr-only nx-select-none"&gt; (opens in a new tab)&lt;/SPAN&gt;&lt;/A&gt; installed in &lt;A href="https://code.visualstudio.com/" target="_blank" rel="noopener noreferrer"&gt;VSCode&lt;SPAN class="nx-sr-only nx-select-none"&gt; (opens in a new tab)&lt;/SPAN&gt;&lt;/A&gt; or &lt;A href="https://docs.github.com/en/copilot/copilot-individual/about-github-copilot-individual" target="_blank" rel="noopener noreferrer"&gt;your IDE of choice&lt;SPAN class="nx-sr-only nx-select-none"&gt; (opens in a new tab)&lt;/SPAN&gt;&lt;/A&gt;.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2 class="nx-not-prose subheading-h2"&gt;&lt;A href="https://code.visualstudio.com/docs/copilot/getting-started#_get-your-first-code-suggestion" target="_blank" rel="noopener noreferrer"&gt;GitHub Copilot Ghost Text&lt;SPAN class="nx-sr-only nx-select-none"&gt; (opens in a new tab)&lt;/SPAN&gt;&lt;/A&gt;&lt;A id="github-copilot-ghost-text" class="subheading-anchor" href="#github-copilot-ghost-text" target="_blank" rel="noopener" aria-label="Permalink for this section"&gt;&lt;/A&gt;&lt;/H2&gt;
&lt;P&gt;Ghost text refers to the light, semi-transparent text suggestions for code provided by GitHub Copilot. This feature is crucial as it allows you to preview the suggested code before accepting or modifying it, helping you maintain control over the final code.&lt;/P&gt;
&lt;P&gt;In order to get the best features of Copilot have your files open in your IDE so that the files can provide information to each other.&lt;/P&gt;
&lt;H3 class="nx-not-prose subheading-h3"&gt;Ghost Text Features&lt;A id="ghost-text-features" class="subheading-anchor" href="#ghost-text-features" target="_blank" rel="noopener" aria-label="Permalink for this section"&gt;&lt;/A&gt;&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;EM&gt;Preview Suggestions:&lt;/EM&gt; Use ghost text to preview the suggested code snippets. This helps you decide whether the suggestion fits your requirements.&lt;/LI&gt;
&lt;LI&gt;&lt;EM&gt;Edit in Real-Time:&lt;/EM&gt; Modify the ghost text directly in your editor. This allows you to tailor the suggestions to better fit your needs without starting from scratch.&lt;/LI&gt;
&lt;LI&gt;&lt;EM&gt;Contextual Understanding:&lt;/EM&gt; The ghost text provides context-aware suggestions, making it easier to integrate new code with existing structures.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2 class="nx-not-prose subheading-h2"&gt;Using Ghost Text to build ServiceNow Service Portal widgets&lt;A id="using-ghost-text-to-build-servicenow-service-portal-widgets" class="subheading-anchor" href="#using-ghost-text-to-build-servicenow-service-portal-widgets" target="_blank" rel="noopener" aria-label="Permalink for this section"&gt;&lt;/A&gt;&lt;/H2&gt;
&lt;H3 class="nx-not-prose subheading-h3"&gt;Apply semantic CSS on an element with the &lt;CODE class="nx-border-black nx-border-opacity-[0.04] nx-bg-opacity-[0.03] nx-bg-black nx-break-words nx-rounded-md nx-border nx-py-0.5 nx-px-[.25em] nx-text-[.9em] dark:nx-border-white/10 dark:nx-bg-white/10" dir="ltr"&gt;ng-class&lt;/CODE&gt; directive&lt;A id="apply-semantic-css-on-an-element-with-the-ng-class-directive" class="subheading-anchor" href="#apply-semantic-css-on-an-element-with-the-ng-class-directive" target="_blank" rel="noopener" aria-label="Permalink for this section"&gt;&lt;/A&gt;&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;Write your CSS with semantic values&lt;/LI&gt;
&lt;/UL&gt;
&lt;DIV class="nx-not-prose"&gt;
&lt;DIV class="nextra-code-block nx-relative nx-mt-6 first:nx-mt-0"&gt;
&lt;PRE class="nx-bg-primary-700/5 nx-mb-4 nx-overflow-x-auto nx-rounded-xl nx-subpixel-antialiased dark:nx-bg-primary-300/10 nx-text-[.9em] contrast-more:nx-border contrast-more:nx-border-primary-900/20 contrast-more:nx-contrast-150 contrast-more:dark:nx-border-primary-100/40 nx-py-4" data-language="css" data-theme="default"&gt;&lt;CODE class="nx-border-black nx-border-opacity-[0.04] nx-bg-opacity-[0.03] nx-bg-black nx-break-words nx-rounded-md nx-border nx-py-0.5 nx-px-[.25em] nx-text-[.9em] dark:nx-border-white/10 dark:nx-bg-white/10" dir="ltr" data-language="css" data-theme="default"&gt;&lt;SPAN class="line"&gt;&lt;SPAN&gt;.badge&lt;/SPAN&gt;&lt;SPAN&gt; {&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;  &lt;SPAN&gt;border-radius&lt;/SPAN&gt;&lt;SPAN&gt;:&lt;/SPAN&gt; &lt;SPAN&gt;5&lt;/SPAN&gt;&lt;SPAN&gt;rem&lt;/SPAN&gt;&lt;SPAN&gt;;&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;  &lt;SPAN&gt;font-family&lt;/SPAN&gt;&lt;SPAN&gt;:&lt;/SPAN&gt; &lt;SPAN&gt;monospaced&lt;/SPAN&gt;&lt;SPAN&gt;;&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;  &lt;SPAN&gt;padding&lt;/SPAN&gt;&lt;SPAN&gt;:&lt;/SPAN&gt; &lt;SPAN&gt;.5&lt;/SPAN&gt;&lt;SPAN&gt;rem&lt;/SPAN&gt;&lt;SPAN&gt; 1&lt;/SPAN&gt;&lt;SPAN&gt;rem&lt;/SPAN&gt;&lt;SPAN&gt;;&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;}&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;.badge-info&lt;/SPAN&gt;&lt;SPAN&gt; {&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;  &lt;SPAN&gt;background&lt;/SPAN&gt;&lt;SPAN&gt;:&lt;/SPAN&gt; &lt;SPAN&gt;darkblue&lt;/SPAN&gt;&lt;SPAN&gt;;&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;  &lt;SPAN&gt;color&lt;/SPAN&gt;&lt;SPAN&gt;:&lt;/SPAN&gt; &lt;SPAN&gt;white&lt;/SPAN&gt;&lt;SPAN&gt;;&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;}&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;.badge-negative&lt;/SPAN&gt;&lt;SPAN&gt; {&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;  &lt;SPAN&gt;background&lt;/SPAN&gt;&lt;SPAN&gt;:&lt;/SPAN&gt; &lt;SPAN&gt;darkred&lt;/SPAN&gt;&lt;SPAN&gt;;&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;  &lt;SPAN&gt;color&lt;/SPAN&gt;&lt;SPAN&gt;:&lt;/SPAN&gt; &lt;SPAN&gt;white&lt;/SPAN&gt;&lt;SPAN&gt;;&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;}&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;.badge-positive&lt;/SPAN&gt;&lt;SPAN&gt; {&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;  &lt;SPAN&gt;background&lt;/SPAN&gt;&lt;SPAN&gt;:&lt;/SPAN&gt; &lt;SPAN&gt;darkgreen&lt;/SPAN&gt;&lt;SPAN&gt;;&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;  &lt;SPAN&gt;color&lt;/SPAN&gt;&lt;SPAN&gt;:&lt;/SPAN&gt; &lt;SPAN&gt;white&lt;/SPAN&gt;&lt;SPAN&gt;;&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;}&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;DIV class="nx-opacity-0 nx-transition [div:hover&amp;gt;&amp;amp;]:nx-opacity-100 focus-within:nx-opacity-100 nx-flex nx-gap-1 nx-absolute nx-m-[11px] nx-right-0 nx-top-0"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;P&gt;When typing an AngularJS directive, such as &lt;CODE class="nx-border-black nx-border-opacity-[0.04] nx-bg-opacity-[0.03] nx-bg-black nx-break-words nx-rounded-md nx-border nx-py-0.5 nx-px-[.25em] nx-text-[.9em] dark:nx-border-white/10 dark:nx-bg-white/10" dir="ltr"&gt;ng-class&lt;/CODE&gt; inside of an &lt;CODE class="nx-border-black nx-border-opacity-[0.04] nx-bg-opacity-[0.03] nx-bg-black nx-break-words nx-rounded-md nx-border nx-py-0.5 nx-px-[.25em] nx-text-[.9em] dark:nx-border-white/10 dark:nx-bg-white/10" dir="ltr"&gt;ng-repeat&lt;/CODE&gt;, ghost text will appear suggesting what CSS semantic values to assign to the element based upon the values being returned from the server.&lt;/P&gt;
&lt;DIV class="nx-not-prose"&gt;
&lt;DIV class="nextra-code-block nx-relative nx-mt-6 first:nx-mt-0"&gt;
&lt;PRE class="nx-bg-primary-700/5 nx-mb-4 nx-overflow-x-auto nx-rounded-xl nx-subpixel-antialiased dark:nx-bg-primary-300/10 nx-text-[.9em] contrast-more:nx-border contrast-more:nx-border-primary-900/20 contrast-more:nx-contrast-150 contrast-more:dark:nx-border-primary-100/40 nx-py-4" data-language="html" data-theme="default"&gt;&lt;CODE class="nx-border-black nx-border-opacity-[0.04] nx-bg-opacity-[0.03] nx-bg-black nx-break-words nx-rounded-md nx-border nx-py-0.5 nx-px-[.25em] nx-text-[.9em] dark:nx-border-white/10 dark:nx-bg-white/10" dir="ltr" data-language="html" data-theme="default"&gt;&lt;SPAN class="line"&gt;&lt;SPAN&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN&gt;li&lt;/SPAN&gt; &lt;SPAN&gt;ng-repeat&lt;/SPAN&gt;&lt;SPAN&gt;=&lt;/SPAN&gt;&lt;SPAN&gt;"item in group"&lt;/SPAN&gt; &lt;SPAN&gt;ng-class&lt;/SPAN&gt;&lt;SPAN&gt;=&lt;/SPAN&gt;&lt;SPAN&gt;"&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;  //'badge badge-info': item.type === 'default'&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;  //'badge badge-negative': item.type === 'success'&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;  //'badge badge-positive': item.type === 'error'&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;  "&lt;/SPAN&gt; &lt;SPAN&gt;ng-bind&lt;/SPAN&gt;&lt;SPAN&gt;=&lt;/SPAN&gt;&lt;SPAN&gt;"item.name"&lt;/SPAN&gt;&lt;SPAN&gt;&amp;gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN&gt;li&lt;/SPAN&gt;&lt;SPAN&gt;&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;DIV class="nx-opacity-0 nx-transition [div:hover&amp;gt;&amp;amp;]:nx-opacity-100 focus-within:nx-opacity-100 nx-flex nx-gap-1 nx-absolute nx-m-[11px] nx-right-0 nx-top-0"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;H3 class="nx-not-prose subheading-h3"&gt;Boilerplate Code&lt;A id="boilerplate-code" class="subheading-anchor" href="#boilerplate-code" target="_blank" rel="noopener" aria-label="Permalink for this section"&gt;&lt;/A&gt;&lt;/H3&gt;
&lt;P&gt;ServiceNow Service Portal widgets often require repetitive boilerplate code. GitHub Copilot can quickly generate this &lt;EM&gt;Client Controller&lt;/EM&gt; Javascript&amp;amp;colon;&lt;/P&gt;
&lt;DIV class="nx-not-prose"&gt;
&lt;DIV class="nextra-code-block nx-relative nx-mt-6 first:nx-mt-0"&gt;
&lt;PRE class="nx-bg-primary-700/5 nx-mb-4 nx-overflow-x-auto nx-rounded-xl nx-subpixel-antialiased dark:nx-bg-primary-300/10 nx-text-[.9em] contrast-more:nx-border contrast-more:nx-border-primary-900/20 contrast-more:nx-contrast-150 contrast-more:dark:nx-border-primary-100/40 nx-py-4" data-language="javascript" data-theme="default"&gt;&lt;CODE class="nx-border-black nx-border-opacity-[0.04] nx-bg-opacity-[0.03] nx-bg-black nx-break-words nx-rounded-md nx-border nx-py-0.5 nx-px-[.25em] nx-text-[.9em] dark:nx-border-white/10 dark:nx-bg-white/10" dir="ltr" data-language="javascript" data-theme="default"&gt;&lt;SPAN class="line"&gt;&lt;SPAN&gt;(&lt;/SPAN&gt;&lt;SPAN&gt;function&lt;/SPAN&gt;&lt;SPAN&gt;() {&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;  &lt;SPAN&gt;// Widget controller&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;  &lt;SPAN&gt;function&lt;/SPAN&gt;&lt;SPAN&gt;($scope&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt;&lt;SPAN&gt; $http) {&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;    &lt;SPAN&gt;// Initialize scope variables&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;    &lt;SPAN&gt;$scope&lt;/SPAN&gt;&lt;SPAN&gt;.data &lt;/SPAN&gt;&lt;SPAN&gt;=&lt;/SPAN&gt;&lt;SPAN&gt; {};&lt;/SPAN&gt;&lt;/SPAN&gt;
    
&lt;SPAN class="line"&gt;    &lt;SPAN&gt;// Function to fetch data&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;    &lt;SPAN&gt;$scope&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;getData&lt;/SPAN&gt; &lt;SPAN&gt;=&lt;/SPAN&gt; &lt;SPAN&gt;function&lt;/SPAN&gt;&lt;SPAN&gt;() {&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;      &lt;SPAN&gt;$http&lt;/SPAN&gt;&lt;SPAN&gt;.get&lt;/SPAN&gt;&lt;SPAN&gt;(&lt;/SPAN&gt;&lt;SPAN&gt;'/api/now/table/your_table'&lt;/SPAN&gt;&lt;SPAN&gt;)&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;        &lt;SPAN&gt;.then&lt;/SPAN&gt;&lt;SPAN&gt;(&lt;/SPAN&gt;&lt;SPAN&gt;function&lt;/SPAN&gt;&lt;SPAN&gt;(response) {&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;          &lt;SPAN&gt;$scope&lt;/SPAN&gt;&lt;SPAN&gt;.data &lt;/SPAN&gt;&lt;SPAN&gt;=&lt;/SPAN&gt; &lt;SPAN&gt;response&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;data&lt;/SPAN&gt;&lt;SPAN&gt;.result;&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;        }&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt; &lt;SPAN&gt;function&lt;/SPAN&gt;&lt;SPAN&gt;(error) {&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;          &lt;SPAN&gt;console&lt;/SPAN&gt;&lt;SPAN&gt;.error&lt;/SPAN&gt;&lt;SPAN&gt;(&lt;/SPAN&gt;&lt;SPAN&gt;'Error fetching data'&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt;&lt;SPAN&gt; error);&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;        });&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;    };&lt;/SPAN&gt;&lt;/SPAN&gt;
    
&lt;SPAN class="line"&gt;    &lt;SPAN&gt;// Call the function to fetch data&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;    &lt;SPAN&gt;$scope&lt;/SPAN&gt;&lt;SPAN&gt;.getData&lt;/SPAN&gt;&lt;SPAN&gt;();&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;  }&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;})();&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;DIV class="nx-opacity-0 nx-transition [div:hover&amp;gt;&amp;amp;]:nx-opacity-100 focus-within:nx-opacity-100 nx-flex nx-gap-1 nx-absolute nx-m-[11px] nx-right-0 nx-top-0"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;P&gt;Ghost text can help ensure the structure is correct before you finalize the code.&lt;/P&gt;
&lt;H3 class="nx-not-prose subheading-h3"&gt;Provide Context with Comments&lt;A id="provide-context-with-comments" class="subheading-anchor" href="#provide-context-with-comments" target="_blank" rel="noopener" aria-label="Permalink for this section"&gt;&lt;/A&gt;&lt;/H3&gt;
&lt;P&gt;Comments guide Copilot to generate more relevant code snippets. Ghost text will adapt to the comments, providing suggestions that align with your described logic.&lt;/P&gt;
&lt;P&gt;For example:&lt;/P&gt;
&lt;DIV class="nx-not-prose"&gt;
&lt;DIV class="nextra-code-block nx-relative nx-mt-6 first:nx-mt-0"&gt;
&lt;PRE class="nx-bg-primary-700/5 nx-mb-4 nx-overflow-x-auto nx-rounded-xl nx-subpixel-antialiased dark:nx-bg-primary-300/10 nx-text-[.9em] contrast-more:nx-border contrast-more:nx-border-primary-900/20 contrast-more:nx-contrast-150 contrast-more:dark:nx-border-primary-100/40 nx-py-4" data-language="javascript" data-theme="default"&gt;&lt;CODE class="nx-border-black nx-border-opacity-[0.04] nx-bg-opacity-[0.03] nx-bg-black nx-break-words nx-rounded-md nx-border nx-py-0.5 nx-px-[.25em] nx-text-[.9em] dark:nx-border-white/10 dark:nx-bg-white/10" dir="ltr" data-language="javascript" data-theme="default"&gt;&lt;SPAN class="line"&gt;&lt;SPAN&gt;(&lt;/SPAN&gt;&lt;SPAN&gt;function&lt;/SPAN&gt;&lt;SPAN&gt;() {&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;  &lt;SPAN&gt;// Widget controller&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;  &lt;SPAN&gt;function&lt;/SPAN&gt;&lt;SPAN&gt;($scope&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt;&lt;SPAN&gt; $http) {&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;    &lt;SPAN&gt;// Initialize scope variables&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;    &lt;SPAN&gt;$scope&lt;/SPAN&gt;&lt;SPAN&gt;.data &lt;/SPAN&gt;&lt;SPAN&gt;=&lt;/SPAN&gt;&lt;SPAN&gt; {};&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;    &lt;SPAN&gt;// Fetch user data from ServiceNow&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;    &lt;SPAN&gt;$scope&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;getUserData&lt;/SPAN&gt; &lt;SPAN&gt;=&lt;/SPAN&gt; &lt;SPAN&gt;function&lt;/SPAN&gt;&lt;SPAN&gt;() {&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;      &lt;SPAN&gt;// Call the ServiceNow API to get user data&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;      &lt;SPAN&gt;$http&lt;/SPAN&gt;&lt;SPAN&gt;.get&lt;/SPAN&gt;&lt;SPAN&gt;(&lt;/SPAN&gt;&lt;SPAN&gt;'/api/now/table/sys_user'&lt;/SPAN&gt;&lt;SPAN&gt;)&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;        &lt;SPAN&gt;.then&lt;/SPAN&gt;&lt;SPAN&gt;(&lt;/SPAN&gt;&lt;SPAN&gt;function&lt;/SPAN&gt;&lt;SPAN&gt;(response) {&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;          &lt;SPAN&gt;// Store the user data in scope&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;          &lt;SPAN&gt;$scope&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;data&lt;/SPAN&gt;&lt;SPAN&gt;.users &lt;/SPAN&gt;&lt;SPAN&gt;=&lt;/SPAN&gt; &lt;SPAN&gt;response&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;data&lt;/SPAN&gt;&lt;SPAN&gt;.result;&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;        }&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt; &lt;SPAN&gt;function&lt;/SPAN&gt;&lt;SPAN&gt;(error) {&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;          &lt;SPAN&gt;console&lt;/SPAN&gt;&lt;SPAN&gt;.error&lt;/SPAN&gt;&lt;SPAN&gt;(&lt;/SPAN&gt;&lt;SPAN&gt;'Error fetching user data'&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt;&lt;SPAN&gt; error);&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;        });&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;    };&lt;/SPAN&gt;&lt;/SPAN&gt;
 
&lt;SPAN class="line"&gt;    &lt;SPAN&gt;// Initialize the widget by fetching user data&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;    &lt;SPAN&gt;$scope&lt;/SPAN&gt;&lt;SPAN&gt;.getUserData&lt;/SPAN&gt;&lt;SPAN&gt;();&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;  }&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;})();&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;DIV class="nx-opacity-0 nx-transition [div:hover&amp;gt;&amp;amp;]:nx-opacity-100 focus-within:nx-opacity-100 nx-flex nx-gap-1 nx-absolute nx-m-[11px] nx-right-0 nx-top-0"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;H2 class="nx-not-prose subheading-h2"&gt;Outro&lt;A id="outro" class="subheading-anchor" href="#outro" target="_blank" rel="noopener" aria-label="Permalink for this section"&gt;&lt;/A&gt;&lt;/H2&gt;
&lt;P&gt;Using GitHub Copilot to write code for ServiceNow Service Portal widgets can significantly enhance your productivity and coding experience. Ghost text, in particular, plays a crucial role by providing context-aware suggestions and allowing real-time editing. By following these best practices, you can harness the power of AI to create robust, efficient, and user-friendly widgets. Always validate and refine the generated code, stay updated with ServiceNow best practices, and continuously seek user feedback for improvement.&lt;/P&gt;
&lt;/ARTICLE&gt;</description>
    <pubDate>Tue, 02 Jul 2024 14:36:32 GMT</pubDate>
    <dc:creator>fauverism</dc:creator>
    <dc:date>2024-07-02T14:36:32Z</dc:date>
    <item>
      <title>Using GitHub Copilot To Build Service Portal Widgets</title>
      <link>https://www.servicenow.com/community/developer-articles/using-github-copilot-to-build-service-portal-widgets/ta-p/2976541</link>
      <description>&lt;ARTICLE class="nx-container nx-prose max-md:nx-prose-sm dark:nx-prose-dark" dir="ltr"&gt;
&lt;DIV class="nx-mb-8 nx-flex nx-gap-3 nx-items-center"&gt;
&lt;DIV class="nx-flex nx-items-center nx-gap-3 print:nx-hidden"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;P&gt;Developing custom ServiceNow Service Portal widgets will enhance the UI and UX of your Portal, including GitHub Copilot while developing can streamline the process significantly. This post will delve into best practices for writing ServiceNow Service Portal widget code.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H2 class="nx-not-prose subheading-h2"&gt;TLDR&lt;A id="tldr" class="subheading-anchor" href="#tldr" target="_blank" rel="noopener" aria-label="Permalink for this section"&gt;&lt;/A&gt;&lt;/H2&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Ghost text, in particular, plays a crucial role by providing context-aware suggestions and allowing real-time editing. Knowing the capabilities of AngularJS directives will aid in provide in suggestions. Have your files open in your IDE will give you more suggestions.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H2 class="nx-not-prose subheading-h2"&gt;Assumptions before you read this&lt;A id="assumptions-before-you-read-this" class="subheading-anchor" href="#assumptions-before-you-read-this" target="_blank" rel="noopener" aria-label="Permalink for this section"&gt;&lt;/A&gt;&lt;/H2&gt;
&lt;UL&gt;
&lt;LI&gt;You know about &lt;A href="https://www.servicenow.com" target="_blank" rel="noopener noreferrer"&gt;ServiceNow&lt;SPAN class="nx-sr-only nx-select-none"&gt; (opens in a new tab)&lt;/SPAN&gt;&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;You have built a &lt;A href="https://docs.servicenow.com/bundle/washingtondc-platform-user-interface/page/build/service-portal/concept/adv-widget-tutorial.html" target="_blank" rel="noopener noreferrer"&gt;Custom ServiceNow Service Portal Widget&lt;SPAN class="nx-sr-only nx-select-none"&gt; (opens in a new tab)&lt;/SPAN&gt;&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;You have &lt;A href="https://github.com/features/copilot" target="_blank" rel="noopener noreferrer"&gt;Github Copilot&lt;SPAN class="nx-sr-only nx-select-none"&gt; (opens in a new tab)&lt;/SPAN&gt;&lt;/A&gt; installed in &lt;A href="https://code.visualstudio.com/" target="_blank" rel="noopener noreferrer"&gt;VSCode&lt;SPAN class="nx-sr-only nx-select-none"&gt; (opens in a new tab)&lt;/SPAN&gt;&lt;/A&gt; or &lt;A href="https://docs.github.com/en/copilot/copilot-individual/about-github-copilot-individual" target="_blank" rel="noopener noreferrer"&gt;your IDE of choice&lt;SPAN class="nx-sr-only nx-select-none"&gt; (opens in a new tab)&lt;/SPAN&gt;&lt;/A&gt;.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2 class="nx-not-prose subheading-h2"&gt;&lt;A href="https://code.visualstudio.com/docs/copilot/getting-started#_get-your-first-code-suggestion" target="_blank" rel="noopener noreferrer"&gt;GitHub Copilot Ghost Text&lt;SPAN class="nx-sr-only nx-select-none"&gt; (opens in a new tab)&lt;/SPAN&gt;&lt;/A&gt;&lt;A id="github-copilot-ghost-text" class="subheading-anchor" href="#github-copilot-ghost-text" target="_blank" rel="noopener" aria-label="Permalink for this section"&gt;&lt;/A&gt;&lt;/H2&gt;
&lt;P&gt;Ghost text refers to the light, semi-transparent text suggestions for code provided by GitHub Copilot. This feature is crucial as it allows you to preview the suggested code before accepting or modifying it, helping you maintain control over the final code.&lt;/P&gt;
&lt;P&gt;In order to get the best features of Copilot have your files open in your IDE so that the files can provide information to each other.&lt;/P&gt;
&lt;H3 class="nx-not-prose subheading-h3"&gt;Ghost Text Features&lt;A id="ghost-text-features" class="subheading-anchor" href="#ghost-text-features" target="_blank" rel="noopener" aria-label="Permalink for this section"&gt;&lt;/A&gt;&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;EM&gt;Preview Suggestions:&lt;/EM&gt; Use ghost text to preview the suggested code snippets. This helps you decide whether the suggestion fits your requirements.&lt;/LI&gt;
&lt;LI&gt;&lt;EM&gt;Edit in Real-Time:&lt;/EM&gt; Modify the ghost text directly in your editor. This allows you to tailor the suggestions to better fit your needs without starting from scratch.&lt;/LI&gt;
&lt;LI&gt;&lt;EM&gt;Contextual Understanding:&lt;/EM&gt; The ghost text provides context-aware suggestions, making it easier to integrate new code with existing structures.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2 class="nx-not-prose subheading-h2"&gt;Using Ghost Text to build ServiceNow Service Portal widgets&lt;A id="using-ghost-text-to-build-servicenow-service-portal-widgets" class="subheading-anchor" href="#using-ghost-text-to-build-servicenow-service-portal-widgets" target="_blank" rel="noopener" aria-label="Permalink for this section"&gt;&lt;/A&gt;&lt;/H2&gt;
&lt;H3 class="nx-not-prose subheading-h3"&gt;Apply semantic CSS on an element with the &lt;CODE class="nx-border-black nx-border-opacity-[0.04] nx-bg-opacity-[0.03] nx-bg-black nx-break-words nx-rounded-md nx-border nx-py-0.5 nx-px-[.25em] nx-text-[.9em] dark:nx-border-white/10 dark:nx-bg-white/10" dir="ltr"&gt;ng-class&lt;/CODE&gt; directive&lt;A id="apply-semantic-css-on-an-element-with-the-ng-class-directive" class="subheading-anchor" href="#apply-semantic-css-on-an-element-with-the-ng-class-directive" target="_blank" rel="noopener" aria-label="Permalink for this section"&gt;&lt;/A&gt;&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;Write your CSS with semantic values&lt;/LI&gt;
&lt;/UL&gt;
&lt;DIV class="nx-not-prose"&gt;
&lt;DIV class="nextra-code-block nx-relative nx-mt-6 first:nx-mt-0"&gt;
&lt;PRE class="nx-bg-primary-700/5 nx-mb-4 nx-overflow-x-auto nx-rounded-xl nx-subpixel-antialiased dark:nx-bg-primary-300/10 nx-text-[.9em] contrast-more:nx-border contrast-more:nx-border-primary-900/20 contrast-more:nx-contrast-150 contrast-more:dark:nx-border-primary-100/40 nx-py-4" data-language="css" data-theme="default"&gt;&lt;CODE class="nx-border-black nx-border-opacity-[0.04] nx-bg-opacity-[0.03] nx-bg-black nx-break-words nx-rounded-md nx-border nx-py-0.5 nx-px-[.25em] nx-text-[.9em] dark:nx-border-white/10 dark:nx-bg-white/10" dir="ltr" data-language="css" data-theme="default"&gt;&lt;SPAN class="line"&gt;&lt;SPAN&gt;.badge&lt;/SPAN&gt;&lt;SPAN&gt; {&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;  &lt;SPAN&gt;border-radius&lt;/SPAN&gt;&lt;SPAN&gt;:&lt;/SPAN&gt; &lt;SPAN&gt;5&lt;/SPAN&gt;&lt;SPAN&gt;rem&lt;/SPAN&gt;&lt;SPAN&gt;;&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;  &lt;SPAN&gt;font-family&lt;/SPAN&gt;&lt;SPAN&gt;:&lt;/SPAN&gt; &lt;SPAN&gt;monospaced&lt;/SPAN&gt;&lt;SPAN&gt;;&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;  &lt;SPAN&gt;padding&lt;/SPAN&gt;&lt;SPAN&gt;:&lt;/SPAN&gt; &lt;SPAN&gt;.5&lt;/SPAN&gt;&lt;SPAN&gt;rem&lt;/SPAN&gt;&lt;SPAN&gt; 1&lt;/SPAN&gt;&lt;SPAN&gt;rem&lt;/SPAN&gt;&lt;SPAN&gt;;&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;}&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;.badge-info&lt;/SPAN&gt;&lt;SPAN&gt; {&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;  &lt;SPAN&gt;background&lt;/SPAN&gt;&lt;SPAN&gt;:&lt;/SPAN&gt; &lt;SPAN&gt;darkblue&lt;/SPAN&gt;&lt;SPAN&gt;;&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;  &lt;SPAN&gt;color&lt;/SPAN&gt;&lt;SPAN&gt;:&lt;/SPAN&gt; &lt;SPAN&gt;white&lt;/SPAN&gt;&lt;SPAN&gt;;&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;}&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;.badge-negative&lt;/SPAN&gt;&lt;SPAN&gt; {&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;  &lt;SPAN&gt;background&lt;/SPAN&gt;&lt;SPAN&gt;:&lt;/SPAN&gt; &lt;SPAN&gt;darkred&lt;/SPAN&gt;&lt;SPAN&gt;;&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;  &lt;SPAN&gt;color&lt;/SPAN&gt;&lt;SPAN&gt;:&lt;/SPAN&gt; &lt;SPAN&gt;white&lt;/SPAN&gt;&lt;SPAN&gt;;&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;}&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;.badge-positive&lt;/SPAN&gt;&lt;SPAN&gt; {&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;  &lt;SPAN&gt;background&lt;/SPAN&gt;&lt;SPAN&gt;:&lt;/SPAN&gt; &lt;SPAN&gt;darkgreen&lt;/SPAN&gt;&lt;SPAN&gt;;&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;  &lt;SPAN&gt;color&lt;/SPAN&gt;&lt;SPAN&gt;:&lt;/SPAN&gt; &lt;SPAN&gt;white&lt;/SPAN&gt;&lt;SPAN&gt;;&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;}&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;DIV class="nx-opacity-0 nx-transition [div:hover&amp;gt;&amp;amp;]:nx-opacity-100 focus-within:nx-opacity-100 nx-flex nx-gap-1 nx-absolute nx-m-[11px] nx-right-0 nx-top-0"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;P&gt;When typing an AngularJS directive, such as &lt;CODE class="nx-border-black nx-border-opacity-[0.04] nx-bg-opacity-[0.03] nx-bg-black nx-break-words nx-rounded-md nx-border nx-py-0.5 nx-px-[.25em] nx-text-[.9em] dark:nx-border-white/10 dark:nx-bg-white/10" dir="ltr"&gt;ng-class&lt;/CODE&gt; inside of an &lt;CODE class="nx-border-black nx-border-opacity-[0.04] nx-bg-opacity-[0.03] nx-bg-black nx-break-words nx-rounded-md nx-border nx-py-0.5 nx-px-[.25em] nx-text-[.9em] dark:nx-border-white/10 dark:nx-bg-white/10" dir="ltr"&gt;ng-repeat&lt;/CODE&gt;, ghost text will appear suggesting what CSS semantic values to assign to the element based upon the values being returned from the server.&lt;/P&gt;
&lt;DIV class="nx-not-prose"&gt;
&lt;DIV class="nextra-code-block nx-relative nx-mt-6 first:nx-mt-0"&gt;
&lt;PRE class="nx-bg-primary-700/5 nx-mb-4 nx-overflow-x-auto nx-rounded-xl nx-subpixel-antialiased dark:nx-bg-primary-300/10 nx-text-[.9em] contrast-more:nx-border contrast-more:nx-border-primary-900/20 contrast-more:nx-contrast-150 contrast-more:dark:nx-border-primary-100/40 nx-py-4" data-language="html" data-theme="default"&gt;&lt;CODE class="nx-border-black nx-border-opacity-[0.04] nx-bg-opacity-[0.03] nx-bg-black nx-break-words nx-rounded-md nx-border nx-py-0.5 nx-px-[.25em] nx-text-[.9em] dark:nx-border-white/10 dark:nx-bg-white/10" dir="ltr" data-language="html" data-theme="default"&gt;&lt;SPAN class="line"&gt;&lt;SPAN&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN&gt;li&lt;/SPAN&gt; &lt;SPAN&gt;ng-repeat&lt;/SPAN&gt;&lt;SPAN&gt;=&lt;/SPAN&gt;&lt;SPAN&gt;"item in group"&lt;/SPAN&gt; &lt;SPAN&gt;ng-class&lt;/SPAN&gt;&lt;SPAN&gt;=&lt;/SPAN&gt;&lt;SPAN&gt;"&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;  //'badge badge-info': item.type === 'default'&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;  //'badge badge-negative': item.type === 'success'&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;  //'badge badge-positive': item.type === 'error'&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;  "&lt;/SPAN&gt; &lt;SPAN&gt;ng-bind&lt;/SPAN&gt;&lt;SPAN&gt;=&lt;/SPAN&gt;&lt;SPAN&gt;"item.name"&lt;/SPAN&gt;&lt;SPAN&gt;&amp;gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN&gt;li&lt;/SPAN&gt;&lt;SPAN&gt;&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;DIV class="nx-opacity-0 nx-transition [div:hover&amp;gt;&amp;amp;]:nx-opacity-100 focus-within:nx-opacity-100 nx-flex nx-gap-1 nx-absolute nx-m-[11px] nx-right-0 nx-top-0"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;H3 class="nx-not-prose subheading-h3"&gt;Boilerplate Code&lt;A id="boilerplate-code" class="subheading-anchor" href="#boilerplate-code" target="_blank" rel="noopener" aria-label="Permalink for this section"&gt;&lt;/A&gt;&lt;/H3&gt;
&lt;P&gt;ServiceNow Service Portal widgets often require repetitive boilerplate code. GitHub Copilot can quickly generate this &lt;EM&gt;Client Controller&lt;/EM&gt; Javascript&amp;amp;colon;&lt;/P&gt;
&lt;DIV class="nx-not-prose"&gt;
&lt;DIV class="nextra-code-block nx-relative nx-mt-6 first:nx-mt-0"&gt;
&lt;PRE class="nx-bg-primary-700/5 nx-mb-4 nx-overflow-x-auto nx-rounded-xl nx-subpixel-antialiased dark:nx-bg-primary-300/10 nx-text-[.9em] contrast-more:nx-border contrast-more:nx-border-primary-900/20 contrast-more:nx-contrast-150 contrast-more:dark:nx-border-primary-100/40 nx-py-4" data-language="javascript" data-theme="default"&gt;&lt;CODE class="nx-border-black nx-border-opacity-[0.04] nx-bg-opacity-[0.03] nx-bg-black nx-break-words nx-rounded-md nx-border nx-py-0.5 nx-px-[.25em] nx-text-[.9em] dark:nx-border-white/10 dark:nx-bg-white/10" dir="ltr" data-language="javascript" data-theme="default"&gt;&lt;SPAN class="line"&gt;&lt;SPAN&gt;(&lt;/SPAN&gt;&lt;SPAN&gt;function&lt;/SPAN&gt;&lt;SPAN&gt;() {&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;  &lt;SPAN&gt;// Widget controller&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;  &lt;SPAN&gt;function&lt;/SPAN&gt;&lt;SPAN&gt;($scope&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt;&lt;SPAN&gt; $http) {&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;    &lt;SPAN&gt;// Initialize scope variables&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;    &lt;SPAN&gt;$scope&lt;/SPAN&gt;&lt;SPAN&gt;.data &lt;/SPAN&gt;&lt;SPAN&gt;=&lt;/SPAN&gt;&lt;SPAN&gt; {};&lt;/SPAN&gt;&lt;/SPAN&gt;
    
&lt;SPAN class="line"&gt;    &lt;SPAN&gt;// Function to fetch data&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;    &lt;SPAN&gt;$scope&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;getData&lt;/SPAN&gt; &lt;SPAN&gt;=&lt;/SPAN&gt; &lt;SPAN&gt;function&lt;/SPAN&gt;&lt;SPAN&gt;() {&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;      &lt;SPAN&gt;$http&lt;/SPAN&gt;&lt;SPAN&gt;.get&lt;/SPAN&gt;&lt;SPAN&gt;(&lt;/SPAN&gt;&lt;SPAN&gt;'/api/now/table/your_table'&lt;/SPAN&gt;&lt;SPAN&gt;)&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;        &lt;SPAN&gt;.then&lt;/SPAN&gt;&lt;SPAN&gt;(&lt;/SPAN&gt;&lt;SPAN&gt;function&lt;/SPAN&gt;&lt;SPAN&gt;(response) {&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;          &lt;SPAN&gt;$scope&lt;/SPAN&gt;&lt;SPAN&gt;.data &lt;/SPAN&gt;&lt;SPAN&gt;=&lt;/SPAN&gt; &lt;SPAN&gt;response&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;data&lt;/SPAN&gt;&lt;SPAN&gt;.result;&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;        }&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt; &lt;SPAN&gt;function&lt;/SPAN&gt;&lt;SPAN&gt;(error) {&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;          &lt;SPAN&gt;console&lt;/SPAN&gt;&lt;SPAN&gt;.error&lt;/SPAN&gt;&lt;SPAN&gt;(&lt;/SPAN&gt;&lt;SPAN&gt;'Error fetching data'&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt;&lt;SPAN&gt; error);&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;        });&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;    };&lt;/SPAN&gt;&lt;/SPAN&gt;
    
&lt;SPAN class="line"&gt;    &lt;SPAN&gt;// Call the function to fetch data&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;    &lt;SPAN&gt;$scope&lt;/SPAN&gt;&lt;SPAN&gt;.getData&lt;/SPAN&gt;&lt;SPAN&gt;();&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;  }&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;})();&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;DIV class="nx-opacity-0 nx-transition [div:hover&amp;gt;&amp;amp;]:nx-opacity-100 focus-within:nx-opacity-100 nx-flex nx-gap-1 nx-absolute nx-m-[11px] nx-right-0 nx-top-0"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;P&gt;Ghost text can help ensure the structure is correct before you finalize the code.&lt;/P&gt;
&lt;H3 class="nx-not-prose subheading-h3"&gt;Provide Context with Comments&lt;A id="provide-context-with-comments" class="subheading-anchor" href="#provide-context-with-comments" target="_blank" rel="noopener" aria-label="Permalink for this section"&gt;&lt;/A&gt;&lt;/H3&gt;
&lt;P&gt;Comments guide Copilot to generate more relevant code snippets. Ghost text will adapt to the comments, providing suggestions that align with your described logic.&lt;/P&gt;
&lt;P&gt;For example:&lt;/P&gt;
&lt;DIV class="nx-not-prose"&gt;
&lt;DIV class="nextra-code-block nx-relative nx-mt-6 first:nx-mt-0"&gt;
&lt;PRE class="nx-bg-primary-700/5 nx-mb-4 nx-overflow-x-auto nx-rounded-xl nx-subpixel-antialiased dark:nx-bg-primary-300/10 nx-text-[.9em] contrast-more:nx-border contrast-more:nx-border-primary-900/20 contrast-more:nx-contrast-150 contrast-more:dark:nx-border-primary-100/40 nx-py-4" data-language="javascript" data-theme="default"&gt;&lt;CODE class="nx-border-black nx-border-opacity-[0.04] nx-bg-opacity-[0.03] nx-bg-black nx-break-words nx-rounded-md nx-border nx-py-0.5 nx-px-[.25em] nx-text-[.9em] dark:nx-border-white/10 dark:nx-bg-white/10" dir="ltr" data-language="javascript" data-theme="default"&gt;&lt;SPAN class="line"&gt;&lt;SPAN&gt;(&lt;/SPAN&gt;&lt;SPAN&gt;function&lt;/SPAN&gt;&lt;SPAN&gt;() {&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;  &lt;SPAN&gt;// Widget controller&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;  &lt;SPAN&gt;function&lt;/SPAN&gt;&lt;SPAN&gt;($scope&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt;&lt;SPAN&gt; $http) {&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;    &lt;SPAN&gt;// Initialize scope variables&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;    &lt;SPAN&gt;$scope&lt;/SPAN&gt;&lt;SPAN&gt;.data &lt;/SPAN&gt;&lt;SPAN&gt;=&lt;/SPAN&gt;&lt;SPAN&gt; {};&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;    &lt;SPAN&gt;// Fetch user data from ServiceNow&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;    &lt;SPAN&gt;$scope&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;getUserData&lt;/SPAN&gt; &lt;SPAN&gt;=&lt;/SPAN&gt; &lt;SPAN&gt;function&lt;/SPAN&gt;&lt;SPAN&gt;() {&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;      &lt;SPAN&gt;// Call the ServiceNow API to get user data&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;      &lt;SPAN&gt;$http&lt;/SPAN&gt;&lt;SPAN&gt;.get&lt;/SPAN&gt;&lt;SPAN&gt;(&lt;/SPAN&gt;&lt;SPAN&gt;'/api/now/table/sys_user'&lt;/SPAN&gt;&lt;SPAN&gt;)&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;        &lt;SPAN&gt;.then&lt;/SPAN&gt;&lt;SPAN&gt;(&lt;/SPAN&gt;&lt;SPAN&gt;function&lt;/SPAN&gt;&lt;SPAN&gt;(response) {&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;          &lt;SPAN&gt;// Store the user data in scope&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;          &lt;SPAN&gt;$scope&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;data&lt;/SPAN&gt;&lt;SPAN&gt;.users &lt;/SPAN&gt;&lt;SPAN&gt;=&lt;/SPAN&gt; &lt;SPAN&gt;response&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;data&lt;/SPAN&gt;&lt;SPAN&gt;.result;&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;        }&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt; &lt;SPAN&gt;function&lt;/SPAN&gt;&lt;SPAN&gt;(error) {&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;          &lt;SPAN&gt;console&lt;/SPAN&gt;&lt;SPAN&gt;.error&lt;/SPAN&gt;&lt;SPAN&gt;(&lt;/SPAN&gt;&lt;SPAN&gt;'Error fetching user data'&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt;&lt;SPAN&gt; error);&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;        });&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;    };&lt;/SPAN&gt;&lt;/SPAN&gt;
 
&lt;SPAN class="line"&gt;    &lt;SPAN&gt;// Initialize the widget by fetching user data&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;    &lt;SPAN&gt;$scope&lt;/SPAN&gt;&lt;SPAN&gt;.getUserData&lt;/SPAN&gt;&lt;SPAN&gt;();&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;  }&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;SPAN class="line"&gt;&lt;SPAN&gt;})();&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;DIV class="nx-opacity-0 nx-transition [div:hover&amp;gt;&amp;amp;]:nx-opacity-100 focus-within:nx-opacity-100 nx-flex nx-gap-1 nx-absolute nx-m-[11px] nx-right-0 nx-top-0"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;H2 class="nx-not-prose subheading-h2"&gt;Outro&lt;A id="outro" class="subheading-anchor" href="#outro" target="_blank" rel="noopener" aria-label="Permalink for this section"&gt;&lt;/A&gt;&lt;/H2&gt;
&lt;P&gt;Using GitHub Copilot to write code for ServiceNow Service Portal widgets can significantly enhance your productivity and coding experience. Ghost text, in particular, plays a crucial role by providing context-aware suggestions and allowing real-time editing. By following these best practices, you can harness the power of AI to create robust, efficient, and user-friendly widgets. Always validate and refine the generated code, stay updated with ServiceNow best practices, and continuously seek user feedback for improvement.&lt;/P&gt;
&lt;/ARTICLE&gt;</description>
      <pubDate>Tue, 02 Jul 2024 14:36:32 GMT</pubDate>
      <guid>https://www.servicenow.com/community/developer-articles/using-github-copilot-to-build-service-portal-widgets/ta-p/2976541</guid>
      <dc:creator>fauverism</dc:creator>
      <dc:date>2024-07-02T14:36:32Z</dc:date>
    </item>
  </channel>
</rss>

