Study guide
11.1 Visualforce Pages & Markup
Salesforce Certified Platform Developer I Exam
Track your progress as you read
Finished sections get a check mark.
1 Introduction & Exam Overview
1.1 Current Exam Facts 1.2 Blueprint Weights & Study Strategy
2 Platform Fundamentals
2.1 Multi-Tenant Architecture & Shared Resources 2.2 MVC Mapping on the Lightning Platform 2.3 Declarative vs Programmatic Decisions 2.4 Agentforce for Developers: Use Cases & Limitations
3 Data Modeling & Schema
3.1 Objects, Fields & Schema Design 3.2 Relationship Types & Implications 3.3 Schema Design Impact on Apex 3.4 Data Import & Export for Development
4 Platform Data Features
4.1 Formula Fields & Roll-Up Summaries 4.2 Core CRM Objects & Standard Schema 4.3 AppExchange Extensions & Platform Boundaries
5 Declarative Process Automation
5.1 Record-Triggered Flows & Declarative Automation 5.2 Approval Processes & Business Rules 5.3 When to Use Apex vs Declarative Tools
6 Apex Language Basics
6.1 Variables, Constants & Apex Data Types 6.2 Lists, Sets & Maps 6.3 Control Flow & Exception Handling 6.4 Classes, Interfaces & OOP Patterns
7 SOQL, SOSL & DML
7.1 SOQL Query Fundamentals 7.2 SOSL Search Fundamentals 7.3 DML Operations & Bulkification 7.4 Governor Limits & Transaction Boundaries
8 Apex Triggers & Order of Execution
8.1 Trigger Structure & Context Variables 8.2 Bulk Trigger Patterns & Best Practices 8.3 Save Order of Execution 8.4 Recursion, Cascading & Transaction Control
9 Asynchronous Apex
9.1 @future Methods 9.2 Queueable Apex 9.3 Batch Apex 9.4 Schedulable Apex & Job Orchestration
10 Security, Events & Schema Access
10.1 Sharing, FLS, CRUD & Injection Prevention 10.2 Platform Events Publish & Subscribe 10.3 Programmatic Schema Access (Describe)
11 Visualforce
11.1 Visualforce Pages & Markup 11.2 Standard, Custom Controllers & Extensions 11.3 Visualforce in Lightning Experience
12 Lightning Components
12.1 Lightning Component Framework Benefits 12.2 Aura Component Structure & Resources 12.3 Lightning Web Components Fundamentals 12.4 LWC Data Access: Wire, Imperative & Events
13 UI Composition & Apex Integration Patterns
13.1 Composing UI in Lightning Apps 13.2 UI Security, Performance & Accessibility Patterns 13.3 Apex Actions for Flow, LWC, and Agentforce
14 Apex Testing
14.1 Testing Framework & Coverage Requirements 14.2 Writing Unit Tests for Triggers & Classes 14.3 Test Data Strategies & Isolation 14.4 Executing Tests & Execute Anonymous Differences
15 Debugging & Developer Tools
15.1 Debug Logs & Monitoring 15.2 Developer Console, CLI, VS Code & Workbench 15.3 Sandboxes, Scratch Orgs & Environment Strategy
16 Deployment & Release
16.1 Change Sets & Metadata Deployment 16.2 Unlocked Packages, Metadata API & Salesforce DX 16.3 Release Readiness & Credential Maintenance
11.1 Visualforce Pages & Markup
Key Takeaways Explain This Topic AI
A Visualforce page is an apex:page root with markup that mixes standard components, HTML, CSS, and JavaScript bound to a controller via merge-field expressions
Use apex:form with inputField/outputField and pageBlock structure for layout; dataTable and apex:repeat iterate collections for lists
Expression syntax {! } binds properties and methods on the controller or standard controller record; static resources host CSS, JS, and images
View state stores form and controller state between postbacks and is capped at 170 KB per page (the old 135 KB figure is stale)—large pages and excess state cause ViewStateMaxSizeExceeded
Platform Developer I still tests Visualforce markup and MVC patterns; for new UI, prefer Lightning Web Components while retaining VF for legacy, PDF, and some embedded scenarios
Last updated: August 2026
11.1 Visualforce Pages & Markup
Quick Answer: A Visualforce (VF) page is server-rendered markup under an <apex:page> root. You compose standard components ( form , pageBlock , inputField , outputField , dataTable , repeat , and others), bind data with {! } merge expressions , attach static resources for CSS/JS/images, and manage view state size on postbacks. On Platform Developer I, VF remains a tested User Interface skill even though Lightning Web Components (LWC) are preferred for most new interactive UI.
Visualforce is the classic Salesforce MVC view technology: markup is the View , the controller (standard, custom, or extension) is the Controller , and sObjects/fields are the Model . This section focuses on pages and markup . Section 11.2 covers controllers; 11.3 covers Lightning Experience embedding and migration judgment.
Why Visualforce Still Matters on PDI
UI is about 25% of the current blueprint. Exam items may ask you to:
- Read a page snippet and predict what renders or which attribute is wrong
- Choose standard controller vs custom controller vs extension (next section)
- Recognize view state problems or missing apex:form around command buttons
- Contrast VF with Aura/LWC for a greenfield requirement
You are not expected to build a full enterprise SPA in VF on the exam. You are expected to know structure, binding, common components, and when VF is the wrong default for new work.
The apex:page Root
Every page starts with <apex:page> . Important attributes you should recognize:
Attribute Role
standardController Name of the standard or custom object (for example, Account )—provides the record context and standard actions
- extensions Comma-separated Apex classes that extend the standard (or custom) controller
- controller Apex class name for a custom controller (no standard controller)
- recordSetVar Variable name for the list of records when using a standard list controller
- action Method run before the page renders (for example, init logic)
- renderAs Often pdf for PDF generation
sidebar / showHeader / applyHtmlTag / applyBodyTag Chrome and HTML shell control—especially relevant when embedding
- docType HTML doctype when you need modern HTML/CSS behavior
- lightningStylesheets Applies Lightning-like styling in Lightning Experience (see 11.3)
- Minimal page with a standard controller: <apex:page standardController="Account">
- <apex:form>
- <apex:pageBlock title="Account">
- <apex:pageBlockSection>
- <apex:outputField value="{!Account.Name}"/>
- <apex:inputField value="{!Account.Phone}"/>
- </apex:pageBlockSection>
- <apex:pageBlockButtons>
- <apex:commandButton action="{!save}" value="Save"/>
- </apex:pageBlockButtons>
- </apex:pageBlock>
- </apex:form>
- </apex:page>
- Rules of thumb
You cannot use both controller and standardController on the same page as peers in the “pick one primary controller” sense used on the exam: custom controller or standard controller (+ optional extensions).
extensions require a constructor that accepts the standard (or custom) controller type.
Without apex:form , postback components like apex:commandButton cannot submit the view state correctly for typical save/edit patterns.
Expression Syntax: {! }
Merge fields evaluate expressions against the controller context:
{!Account.Name} — field on the standard controller’s record (object API name as root when standardController="Account" )
- {!myProperty} — getter property on a custom controller or extension
- {!myMethod} — action method for buttons/links (no parentheses in markup)
{!IF(condition, a, b)} , {!URLFOR(...)} , {!$ObjectType.Account.fields.Name.label} — formula-style and global variables
Global merge variables you will see: $User , $Profile , $ObjectType , $Resource , $Label , $Page , $Action , $Setup , and more.
- Static resource reference: <apex:stylesheet value="{!$Resource.MyStyles}"/>
- <apex:includeScript value="{!$Resource.MyScript}"/>
- <!-- Zip static resource path -->
- <apex:image value="{!URLFOR($Resource.MyZip, 'images/logo.png')}"/>
Exam trap: Expressions are case-insensitive for many identifiers but field/API names must match the schema. A misspelled property fails at runtime or design-time validation depending on context.
- Core Standard Components
- Structure and layout
- Component Purpose
- apex:pageBlock Salesforce-styled block with title
- apex:pageBlockSection Multi-column section inside a pageBlock
- apex:pageBlockSectionItem Label/value pair control when not using inputField/outputField auto-layout
- apex:pageBlockButtons Button bar (top/bottom of pageBlock)
- apex:pageBlockTable Table bound to a list; Salesforce styling
- apex:sectionHeader Title/subtitle header
- apex:tabPanel / apex:tab Tabbed UI
- Forms and fields
- Component Purpose
- apex:form Required container for postbacks and view state
- apex:inputField Renders the correct editor for the field type and enforces FLS presentation
- apex:outputField Read-only field display with correct type formatting
apex:inputText / inputTextarea / inputCheckbox / selectList Generic inputs when not binding typed sObject fields
- apex:commandButton / commandLink Submit form; action points to controller method
- apex:actionSupport / actionFunction / actionPoller / actionStatus Partial-page AJAX behaviors
- apex:message / apex:messages / apex:pageMessages Validation and Apex addMessage display
inputField vs generic inputs: Prefer inputField when bound to sObject fields so field type, picklist values, and dependent picklists work with less custom code. Generic inputs need manual validation and do not automatically apply field-level help/type widgets.
- Iteration: dataTable , pageBlockTable , repeat <apex:pageBlockTable value="{!Account.Contacts}" var="c">
- <apex:column value="{!c.Name}"/>
- <apex:column value="{!c.Email}"/>
- </apex:pageBlockTable>
- <apex:dataTable value="{!items}" var="row" id="tbl">
- <apex:column headerValue="Name">
- <apex:outputText value="{!row.Name}"/>
- </apex:column>
- </apex:dataTable>
- <apex:repeat value="{!items}" var="row">
- <div class="row">{!row.Name}</div>
- </apex:repeat>
- Component When to choose
- pageBlockTable Standard Salesforce table look inside pageBlocks
- dataTable HTML table with more control; still server-side iteration
- repeat Full markup control (divs, custom HTML)—no automatic table chrome
All three need a value collection and a var loop variable. Nested repeats are allowed but increase view state and complexity.
Incorporating HTML, CSS, and JavaScript
Visualforce allows raw HTML inside the page (subject to platform security and component nesting rules). Common patterns:
Inline styles/scripts for tiny demos—avoid for production; hard to cache and reuse.
Static resources for CSS, JS libraries, fonts, and images (single files or zips).
apex:includeScript / apex:stylesheet so dependencies load in a controlled order.
JavaScript remoting ( @RemoteAction ) or actionFunction when you need client→Apex without full classic postbacks (remoting is controller-side; markup still hosts the JS).
Security note: Escape untrusted data. Prefer apex:outputText with default escaping over dumping raw HTML. Cross-site scripting risks appear when you disable escaping ( escape="false" ) carelessly.
CSS scope: Classic VF pages do not automatically look like Lightning. Use lightningStylesheets="true" (11.3) or custom CSS for Lightning Experience polish. Component IDs in the DOM are often prefixed—use $Component in expressions when wiring JS to VF-generated client IDs.
Static Resources
Static resources are org-stored files (max size per resource is platform-limited; zip archives are common). Benefits for the exam narrative:
- Cached and versioned with the org
- Referenced with $Resource
- Shared across many pages
- Better than Document/Attachment links for UI assets
Upload a zip with css/app.css and js/app.js , then reference paths with URLFOR($Resource.ZipName, 'css/app.css') .
View State: Concept and Size Limits
View state is the serialized snapshot of the page’s non-transient controller state, form data, and component tree that Salesforce posts back with each form submission so the page can restore context between requests.
- Why it matters
- Large tables, non-transient collections, and deep component trees inflate view state
Exceeding the limit throws ViewStateMaxSizeExceededException . The documented maximum is 170 KB per page, and the runtime error text says so literally: “Maximum view state size limit (170KB) exceeded.” Older study material still quotes the pre-increase 135 KB figure—treat 135 KB as stale and 170 KB as current
- Only applies to stateful VF form postbacks—not to pure client-side LWC the same way
- Mitigations the exam expects you to recognize
- Technique Effect
- Mark large controller properties transient Excluded from view state; re-query or rebuild each request
- Reduce rows shown; paginate ( StandardSetController ) Smaller component/state graph
- Prefer outputField / fewer input components when possible Less form state
- Avoid stuffing huge Maps/Lists into non-transient properties Direct size cut
Use JavaScript remoting / redesign for partial patterns Can avoid full classic view-state postbacks for some interactions
Split complex UIs into multiple pages or Lightning components Architectural relief
Exam scenario: A page works for admins testing with 5 rows but fails for users with 500 child records in a non-paginated pageBlockTable bound to a non-transient list—classic view-state (or heap) pain. Pagination and transient are first-line answers.
When VF Appears vs LWC Preference for New UI
Situation Lean toward
New interactive record UI, App Builder composition, mobile-friendly Lightning LWC (or Aura only when required for legacy APIs)
Existing VF pages that work, PDF generation ( renderAs="pdf" ), email templates-adjacent HTML, certain console/legacy embeds Keep VF until migration cost is justified
Exam question: “best long-term UI framework for a new component in Lightning Experience” Usually LWC
Exam question: debug standard controller field binding, view state, or extension constructors Visualforce knowledge
Bottom line for 11.1: Know apex:page , form + field components , iteration components , {! } + $Resource , and view state awareness. Use VF fluently for legacy and exam scenarios; default new UI design conversations to LWC unless a VF-specific capability (PDF, existing investment) dominates.