Ad Selection Panel

SEEK provides a themeable Ad Selection Panel you can embed within your job posting flow. It displays the SEEK ad products available to the hirer along with their associated prices.

Browser support

The Ad Selection Panel tracks our standard browser support policy.
While the panel is currently functional in Internet Explorer 11, backward compatibility will be dropped in a future revision. We are not able to provide ongoing support for Internet Explorer as it is retired and out of support .

Step 1: Include the panel

Add the following script tag to the page where you want to insert the Ad Selection Panel:
HTML
Copy
<script
  type="text/javascript"
  src="https://seekcdn.com/hirer/indirect-posting/product-selection-panel/seek.js"
></script>

Step 2: Render the panel

The render method renders an instance of the panel in the specified DOM element.
This method must be called on page load and whenever the properties of the draftAdvertisement object change. For example, if the hirer selects a new location, you must re-render the panel to reflect updated pricing.
The panel is responsive  and will inherit the width of the containerNode’s parent. If you don’t have any preference for the panel’s width, we recommend that you add a max-width: 822px style to the parent of the containerNode.

Example JavaScript

JavaScript
Copy
SEEKAdPostingWidget.render(containerNode, options);
  • containerNode – (DOM Node) The DOM element to render the widget into.
  • options – Options for rendering the panel; see options below.

Options

Option property
Type
Description
instanceId
string
optional
A unique identifier for the new instance. This will be passed into callback methods. Should be unique per instance of the panel on the page.
mode
string
Create or Update.
onInitialLoad(event)
() => void
optional
Function to call when panel is loaded.
event (object)
  • instanceId (string | undefined)
  • isVisible (boolean)
    Flag indicating whether the panel is visible.
onChange(event)
() => void
getAuthToken
() => Promise<string>
Function to call to retrieve the browser token to use when calling the SEEK API.
isValidationEnabled
boolean
Flag indicating whether to show an error message when draftAdvertisement.typeCode is undefined. This will typically be false until the hirer presses save.
draftAdvertisement
object
The proposed state of the job ad to be posted or updated.
draftAdvertisement.typeCode
string
optional
One of: Classic, StandOut, or Premium.
Update mode only.
draftAdvertisement.hirerJobReference
string
optional
≤50 characters
draftAdvertisement.positionTitle
string
optional
draftAdvertisement.jobCategoryId
string
optional
The identifier for the position’s job category.
e.g. seekAnzPublicTest:jobCategory:seek:27HXTkNXh
draftAdvertisement.positionLocationId
string
optional
The identifier for the position’s location.
advertisement
object
optional
The current state of the posted job ad.
Update mode only.
advertisement.id
string
optional
The position profile ID of the job ad.
If this is provided, the other advertisement properties will be loaded automatically.
advertisement.typeCode
string
optional
One of: Classic, StandOut, or Premium.
advertisement.hirerJobReference
string
optional
≤50 characters
advertisement.positionTitle
string
optional
advertisement.jobCategoryId
string
optional
The identifier for the position’s job category.
e.g. seekAnzPublicTest:jobCategory:seek:2PiXemmou
advertisement.positionLocationId
string
optional
The identifier for the position’s location.
theme
object
optional
Options for configuring the look of the panel.
theme.selectionColor
string
default: #e60278
The colour to set the product border and description to when a product is selected.
theme.linkColor
string
Defaults to selectionColor
The colour to set links and popup triggers to.
theme.contractBarPrimaryBackgroundColor
string
default: #e60278
No longer in use
theme.contractBarSecondaryBackgroundColor
string
default: #fceff5
No longer in use
theme.cautionColor
string
default: #b38800
The colour to set the product message to when the product has a cautionary message for the hirer.
theme.errorColor
string
default: #ff0000
The colour to set the product list border to when isValidationEnabled is set to true and a product hasn’t been selected.
disableCSSOMInjection
boolean
default: false
Disable CSS Object Model injection. Reduces render performance. This may need to be used if the panel is rendering unstyled. See Troubleshooting.

Sample code

JavaScript
Copy
SEEKAdPostingWidget.render(document.getElementById('seekWidget1ContainerDiv'), {
  // Unique identifier for the instance.
  instanceId: 'widget1',

  // Mode should be `Create` while posting a new job ad
  // or `Update` while updating a job ad.
  mode: 'Create',

  // Function to call when panel is loaded.
  onInitialLoad: function (event) {
    const { instanceId, isVisible } = event;
    if (isVisible) {
      console.log(`Widget ${instanceId} loaded`);
      // -> Widget widget1 loaded
    }
  },

  // `onChange` will be called each time a hirer selects an ad product.
  // See "Step 4" for more details.
  onChange: function (event) {
    const { advertisement } = event;

    // `typeCode` should be persisted in memory to be used
    //  for job posting mutations.
    const { typeCode, features } = advertisement;

    console.log(`The hirer selected the ${typeCode} ad product`);
    // -> The hirer selected the Premium ad product

    // Your software should use "features" to conditionally display bullet
    // points and branding inputs based on the selected ad product.
    const { brandingIndicator, searchBulletPointsIndicator } = features;

    if (brandingIndicator) {
      // Show brand selector
    } else {
      // Hide brand selector
    }

    if (searchBulletPointsIndicator) {
      // Show fields to enter bullet points
    } else {
      // Hide bullet point fields
    }
  },

  // Function to call to retrieve the browser token to use
  // when calling the SEEK API, see "Step 3" for more details.
  getAuthToken: function () {
    return Promise.resolve('browser token');
  },

  // `draftAdvertisement` should contain all of the hirer’s
  // current inputs if they are posting or updating.
  draftAdvertisement: {
    positionTitle: 'Developer',
    jobCategoryId: 'seekAnzPublicTest:jobCategory:seek:2EFstqFvP',
    positionLocationId: 'seekAnzPublicTest:location:seek:2TCFhBtw9',
    hirerJobReference: 'Premium521'
  },

  // `advertisement` specifies the current state of the job ad in update mode.
  //
  // Typically you would only specify the `id` of the live job ad.
  // Alternatively, you can provide the job ad's fields if you don't have the
  // position profile ID.
  advertisement: {
    // Position profile ID
    id: 'seekAnzPublicTest:positionProfile:jobAd:27cuZeA47'
  },

  // Specify a `theme` to style your ad selection
  // panel with your own colours.
  theme: {
    selectionColor: '#e60278',
    linkColor: '#e60278',
    cautionColor: '#b38800',
    errorColor: '#ff0000'
  }
});

Step 3: Handle browser token requests

  1. The panel loads and invokes the getAuthToken function passed to it.
  2. Your frontend requests a browser token from your backend.
    The getAuthToken function should request a new token for the hirer ID in positionProfile.positionOrganizations. If a user switches to a different SEEK hirer account in your posting form, your software should re-render the panel with the new hirer ID in positionProfile.positionOrganizations, and ensure that subsequent invocations of getAuthToken will request a token for the new hirer ID.
  3. Your backend authenticates and authorises the user.
    Your software is responsible for verifying that the user is authorised to access a given hirer ID. A user must not be able to request a browser token for an arbitrary organization that they do not belong to.
  4. Your backend requests a browser token from the SEEK API for the appropriate hirer ID and query:ad-products query:organizations scope.
  5. Your backend responds with the browser token.
  6. Your frontend returns the browser token from the getAuthToken function.
  7. The panel can now make requests to the GraphQL endpoint.
HTTP
Copy
POST https://graphql.seek.com/auth/token HTTP/1.1
Authorization: Bearer PARTNER_TOKEN_HERE
Content-Type: application/json
User-Agent: YourPartnerService/1.2.3
{
  "hirerId": "seekAnzPublicTest:organization:seek:93WyyF1h",
  "scope": "query:ad-products query:organizations",
  "userId": "317665"
}

Step 4: Handle ad product selection

When a hirer selects an ad product, the onChange function you provided within your options will be called with the below event structure.
The advertisement.typeCode property should be persisted in memory to be used when posting the job ad.

onChange event

Option property
Type
Description
instanceId
string | undefined
The unique identifier initially passed in via options.
advertiserId
string
The ID of the hirer that has selected an ad product.
advertisement.id
string | undefined
The position profile ID of the job ad.
advertisement.hirerJobReference
string | undefined
advertisement.typeCode
The ad product type code selected by the hirer. This should be persisted in memory and used for job posting mutations.
advertisement.jobCategoryId
string | undefined
The identifier for the position’s job category.
advertisement.positionLocationId
string | undefined
The identifier for the position’s location.
advertisement.positionTitle
string | undefined
advertisement.price
integer
The price of the ad product in the minor currency unit. For example, this is the number of cents in dollar-denominated currencies, e.g 26989 would be returned for $269.89 AUD.
advertisement.priceDescription
string
Descriptive summary of the product price, e.g A$269.89 will be deducted from your SEEK contract or A$319.39 + GST. See price for details on how the currency is determined.
advertisement.paymentDueExcludingTax
The amount left to be paid after contract deductions. This is an object with both currency and value properties.
advertisement.features

Supporting features

Ad products have features that dynamically impact your software’s job posting flow. The available features are passed to your onChange handler when an ad product is selected:
Previously these features needed to be inferred from the advertisement.typeCode property. This may not work in the future when additional typeCode values are added.

Step 5: Posting the job ad

When the hirer is ready to post or update the job ad, advertisement.typeCode persisted above should be passed into the CreatePostingInstructionInput.seekAnzAdvertisementType  field in the postPosition , postPositionProfileForOpening  or updatePostedPositionProfile  job posting mutations.
When a hirer submits the form in your software, you will need to toggle isValidationEnabled to true within options to flag to the panel to display a validation error border around the panel if an ad product has not yet been selected.
The validation error border can be styled using the theme.errorColor property within options.

Forward compatibility

Additional advertisement.typeCode values may be added in the future. However, the existing Classic, StandOut & Premium values will continue to be accepted when posting a job ad.
Your software should not have conditional business logic based on the advertisement.typeCode property. This may not work for unexpected advertisement.typeCode values.

Error handling

Fallback

There are errors that can prevent the panel from being shown to hirers. When they occur, you must show a fallback field that allows a hirer to select an advertisement type.
HTML
Copy
<label for="seek-advertisement-type">Ad type</label>
<select id="seek-advertisement-type">
  <option value="">Please choose an option</option>
  <option>Classic</option>
  <option>StandOut</option>
  <option>Premium</option>
</select>
The advertisement type must be selected by the hirer. It must not be defaulted.
You will not have access to the ad product’s features when using the fallback field. Instead, you need to hardcode the supported features within your software:
Advertisement type
Supports search bullets
Supports branding
Classic
StandOut
Premium
You should also show a message informing the hirer that there was an error loading pricing and that they should contact SEEK for pricing.
You could hide the fallback field after onInitialLoad is called with isVisible set to true or you could start by not showing anything and only show the fallback field when an error occurs or if the widget fails to load within a set time frame.

Script doesn’t load properly

If for some reason the hirer’s browser fails to load the script, calling the render method will fail because SEEKAdPostingWidget will be undefined. To handle this, it’s recommended to wrap the call to the render method in a try/catch block.
JavaScript
Copy
try {
  SEEKAdPostingWidget.render(
    document.getElementById('seekWidget1ContainerDiv'),
    options
  );
} catch (e) {
  // Show fallback field if not already visible
}

Panel fails to call onInitialLoad function

When the panel is unable to retrieve prices from the SEEK API, it may fail to call the onInitialLoad function or it may call onInitialLoad with isVisible set to false.
This can be handled 2 different ways:
  1. You could start by showing the fallback field and hide it once onInitialLoad is called with isVisible set to true.
    JavaScript
    Copy
    try {
      const options = {
        onInitialLoad: (event) => {
          if (event.isVisible) {
            // Hide fallback
          }
        }
      };
      SEEKAdPostingWidget.render(container, options);
    } catch (e) {}
  2. You could set a timer and show the fallback field after a set time frame has elapsed and the widget container doesn’t have any children:
    JavaScript
    Copy
    try {
      const container = document.getElementById('seekWidget1ContainerDiv');
      SEEKAdPostingWidget.render(container, options);
    
    
      setTimeout(function () {
        if (!container.children[0]?.children.length > 0) {
          // Show fallback field
        }
      }, 4000);
    } catch (e) {
      // Show fallback field
    }

Troubleshooting

The panel is unstyled

If the panel renders without a stylesheet and looks unstyled, there may be an incompatibility between your software’s front-end framework and the panel’s use of the CSS Object Model .
If this is the case you can set disableCSSOMInjection to true within your panel options.
Please note: disabling CSS Object Model injection reduces rendering performance as it switches to a slower text node-based CSS injection system for adding styles to the DOM.