Creating a controller extension is a two-step process: write the Apex class with the standard controller constructor, then reference it from the Visualforce page tag's extensions attribute. The framework handles the wiring.
- Identify the standard controller
Decide which object the Visualforce page targets: Account, Case, or any custom object. The page tag will declare standardController="ObjectName". Custom objects use their API name (My_Object__c).
- Create the extension Apex class
From the Developer Console or CLI, create a new Apex class. Add a public with sharing class declaration. Define a constructor that takes ApexPages.StandardController and store it in an instance variable.
- Add action methods and properties
Inside the extension, write public methods for any custom button actions, and public properties for any computed values the page should display. Action methods return PageReference (or void for buttons that do not navigate).
- Reference the extension from the Visualforce page
Open the Visualforce page and update the page tag: <apex:page standardController="Account" extensions="AccountExtension">. Multiple extensions are comma-separated.
- Reference extension methods from the markup
Inside the page, bind buttons to extension methods with action="{!methodName}". Reference properties with {!propertyName}. The platform resolves the names against the standard controller first, then the extensions in declaration order.
- Write the test class
Create an Apex test class. Insert a sample record, build the standard controller manually with new ApexPages.StandardController(record), instantiate the extension, and call each action method asserting the returned PageReference or state mutation.
Attribute on the Visualforce page tag that picks the object whose standard controller backs the page. Cannot be combined with the controller attribute.
Comma-separated list of Apex class names that extend the standard controller. Each class must have a constructor accepting ApexPages.StandardController.
The system class representing the standard controller. The extension constructor captures it and uses its methods (getRecord, save, edit, cancel).
The system class for list-view standard controllers. Extensions on list views take this type in the constructor instead.
Modifier on instance variables that excludes them from view state serialization, keeping the page under the 170 KB cap.
Return type used by action methods. Setting setRedirect(true) navigates the browser. Returning null keeps the user on the same page.
- Extensions are constructed every page load. Heavy queries in the constructor inflate page-load time. Move expensive work to lazy properties evaluated on first access.
- View state exists per page render. Storing large lists in non-transient instance variables triggers the 170 KB overflow error. Mark intermediate collections transient.
- Declaration order in the extensions attribute matters for name resolution. If two extensions define a method with the same name, the first one wins.
- The standard controller and the extension share sharing context only if the extension class declares with sharing. Without it, the extension runs in system mode regardless of the page user.
- Controller extensions are a Visualforce concept. Lightning Web Components and Aura Components do not use extensions. The equivalent pattern in Lightning is an Apex class with @AuraEnabled methods called from the component.