Build a SharePoint Resource Center with Dynamic Filtering
In my latest YouTube tutorial, I demonstrate how to build a modern SharePoint Resource Center using nothing but out-of-the-box SharePoint features.
Rather than exposing a traditional document library, this approach creates a guided discovery experience that helps users naturally find the information they need using metadata, Dynamic Filtering, and JSON formatting.
The framework is completely reusable and can be adapted for almost any department, including HR, IT, Facilities, Health & Safety, Finance, and many more.
JSON Resources
Below you'll find the JSON formatting used throughout the video.
Document Library Gallery View JSON
Creates the modern Resource Card layout shown in the tutorial.
{
"height": 230,
"width": 280,
"hideSelection": false,
"fillHorizontally": true,
"formatter": {
"elmType": "div",
"attributes": {
"class": "sp-card-container"
},
"children": [
{
"elmType": "div",
"attributes": {
"class": "ms-bgColor-white sp-css-borderColor-neutralLight sp-card-borderHighlight sp-card-subContainer"
},
"style": {
"height": "100%",
"box-sizing": "border-box",
"border-radius": "14px",
"box-shadow": "0 2px 8px rgba(0,0,0,0.08)",
"padding": "18px",
"display": "flex",
"flex-direction": "column",
"overflow": "hidden"
},
"children": [
{
"elmType": "div",
"style": {
"display": "flex",
"align-items": "center",
"gap": "8px",
"margin-bottom": "14px",
"flex-shrink": "0"
},
"children": [
{
"elmType": "span",
"attributes": {
"iconName": "=if([$FabricIcon] == '', 'Page', [$FabricIcon])"
},
"style": {
"font-size": "21px",
"color": "=if([$ResourceType] == 'Form', '#0078d4', if([$ResourceType] == 'Guide', '#107c10', if([$ResourceType] == 'Policy', '#5c2d91', if([$ResourceType] == 'Video', '#d13438', if([$ResourceType] == 'Template', '#ca5010', if([$ResourceType] == 'Link', '#008575', if([$ResourceType] == 'FAQ', '#ffaa44', if([$ResourceType] == 'Troubleshooting', '#a4262c', if([$ResourceType] == 'Checklist', '#498205', '#605e5c')))))))))"
}
},
{
"elmType": "span",
"txtContent": "=toUpperCase(if([$ResourceType] == '', 'RESOURCE', [$ResourceType]))",
"style": {
"font-size": "11px",
"font-weight": "700",
"letter-spacing": "0.6px",
"padding": "4px 9px",
"border-radius": "999px",
"background-color": "=if([$ResourceType] == 'Form', '#eff6fc', if([$ResourceType] == 'Guide', '#edf7ed', if([$ResourceType] == 'Policy', '#f4eefc', if([$ResourceType] == 'Video', '#fde7e9', if([$ResourceType] == 'Template', '#fff4ce', if([$ResourceType] == 'Link', '#e6f6f4', if([$ResourceType] == 'FAQ', '#fff8e1', if([$ResourceType] == 'Troubleshooting', '#fde7e9', if([$ResourceType] == 'Checklist', '#f1f8e9', '#f3f2f1')))))))))",
"color": "=if([$ResourceType] == 'Form', '#005a9e', if([$ResourceType] == 'Guide', '#0b6a0b', if([$ResourceType] == 'Policy', '#5c2d91', if([$ResourceType] == 'Video', '#a4262c', if([$ResourceType] == 'Template', '#8a3b00', if([$ResourceType] == 'Link', '#006c5b', if([$ResourceType] == 'FAQ', '#8a5a00', if([$ResourceType] == 'Troubleshooting', '#a4262c', if([$ResourceType] == 'Checklist', '#386604', '#323130')))))))))"
}
}
]
},
{
"elmType": "div",
"style": {
"flex": "1 1 auto",
"min-height": "0",
"overflow": "hidden"
},
"children": [
{
"elmType": "div",
"attributes": {
"title": "[$Title]"
},
"txtContent": "=if([$Title] == '', 'Untitled resource', [$Title])",
"style": {
"font-size": "17px",
"font-weight": "600",
"line-height": "22px",
"color": "#201f1e",
"margin-bottom": "8px",
"display": "-webkit-box",
"-webkit-line-clamp": "2",
"-webkit-box-orient": "vertical",
"overflow": "hidden",
"word-break": "normal",
"overflow-wrap": "normal",
"hyphens": "none"
}
},
{
"elmType": "div",
"attributes": {
"title": "[$ItemDescription]"
},
"txtContent": "=if([$ItemDescription] == '', 'No description available.', [$ItemDescription])",
"style": {
"font-size": "13px",
"line-height": "18px",
"color": "#605e5c",
"display": "-webkit-box",
"-webkit-line-clamp": "2",
"-webkit-box-orient": "vertical",
"overflow": "hidden",
"word-break": "normal",
"overflow-wrap": "normal",
"hyphens": "none"
}
}
]
},
{
"elmType": "button",
"customRowAction": {
"action": "defaultClick"
},
"style": {
"margin-top": "14px",
"border": "1px solid #d2d0ce",
"border-radius": "8px",
"background-color": "#ffffff",
"color": "#323130",
"font-size": "13px",
"font-weight": "600",
"padding": "9px 12px",
"cursor": "pointer",
"display": "flex",
"align-items": "center",
"justify-content": "space-between",
"width": "100%",
"box-sizing": "border-box",
"flex-shrink": "0"
},
"children": [
{
"elmType": "span",
"txtContent": "Open Resource"
},
{
"elmType": "span",
"attributes": {
"iconName": "Forward"
},
"style": {
"font-size": "14px"
}
}
]
}
]
}
],
"style": {
"height": "100%",
"overflow": "hidden",
"box-sizing": "border-box",
"padding": "8px"
}
},
"$schema": "https://developer.microsoft.com/json-schemas/sp/v2/tile-formatting.schema.json"
}Fluent UI Icons
The Resource Cards use Microsoft's Fluent UI Icons, allowing you to display different icons for different resource types without creating custom images.
Browse the full icon library here:
https://www.academy365.io/blog/b840a49b-5a1b-41dc-a005-52be919ef9ff
Simply copy the icon name (for example ReadingMode, DocumentSet, or Globe) and paste it into the Fabric Icon column as demonstrated in the video.
Filter List View JSON
Formats the grouped filter headings used in the navigation list.
{
"$schema": "https://developer.microsoft.com/json-schemas/sp/v2/view-formatting.schema.json",
"groupProps": {
"headerFormatter": {
"elmType": "div",
"style": {
"padding": "20px 0 8px 0",
"font-size": "18px",
"font-weight": "700",
"color": "#201f1e",
"border-bottom": "0px solid #e1dfdd",
"margin-bottom": "8px"
},
"children": [
{
"elmType": "span",
"txtContent": "@group.fieldData.displayValue"
}
]
}
}
}I hope you find this useful! If you build your own Resource Center, I'd love to see it. Feel free to leave a comment on the YouTube video and let me know how you've adapted the framework for your own organisation.
Thanks for making it this far! ;-)
Dan