Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for Slot-Size macro replacement on render_url #311

Open
tylerdev0 opened this issue Jun 2, 2022 · 13 comments
Open

Support for Slot-Size macro replacement on render_url #311

tylerdev0 opened this issue Jun 2, 2022 · 13 comments
Labels
Non-breaking Feature Request Feature request for functionality unlikely to break backwards compatibility

Comments

@tylerdev0
Copy link

tylerdev0 commented Jun 2, 2022

I have been working on a Fledge implementation and have come across an issue regarding support for ads with multiple options for dimensions.

For a given ad, we may have multiple different creative dimensions that we support. For example we may have a separate creative for each of the following dimensions: [[160, 600], [245, 250], [300, 250], [300, 600], ...]

We refer to these as "responsive ads" and this allows us to place a bid for a single ad and adapt the creative response based on the slot-size which was communicated through the bid request.

In the current Fledge spec, the render_url for an ad that is included in an interest group is a static url with no support for macro replacement. This means that in order for us to support multiple sizes we must include multiple copies of the same ad within an interest group and our bidding function must manually filter the list of ads to find ads whose creative dimensions match the slot-size.

This duplication of every single ad to include all of the sizes which it supports will eventually become un-scalable for our needs. As an example if we wish to include 100 ads in an interest group, and we must include 15 copies of each ad (one for each dimension we support) it would require us to insert 1,500 ads in an interest group. Not only does this add bloat to the interest group object stored in the browser, but it also impacts the latency of our bidding function as it must perform manual filtering for the slot size.

In addition to impacting the size of the interest group and the performance of the bidding function, this also impacts k-anonymity of our ads in a negative way. Each distinct creative size would be subject to k-anonymity independently even though they are effectively the same ad. For less common slot sizes it would become difficult to meet k-anonymity if we treat each creative dimension as its own ad.

Would it be possible for the render_url to support a macro for the slot height and width so that we can respond with an appropriately sized creative. For example the render_url could be formatted as:
https://cdn.com/url-of-winning-creative.html?size={%SLOT_HEIGHT%}x{%SLOT_WIDTH$}

The exact formatting doesn't really matter as long as there is some method to communicate the slot size at the time of the creative request.

The slot dimensions are already communicated via the contextual request so this should not have any impact on privacy. Slot sizes are fairly standard and determined by the publisher so there should be no risk of this macro leaking any information that could be used by sellers to learn information about the user.

@fhoering
Copy link
Contributor

fhoering commented Jun 3, 2022

+1 We also have the same issue. We currently bypassed this by injecting the width and height on our own with Javascript during rendering. It works because stuff is still rendered the iframe but it won't work with the fenced frame implementation.

function buildFullCasperUrl(url, w, h) {
    return url + "&width=" + w + "&height=" + h;
}

function invoke(url) {
    const vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0);
    const vh = Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0);
    const fullUrl = buildFullCasperUrl(url, vw, vh);
    document.write("<iframe frameborder='0' scrolling='no' src='"+fullUrl+"' width='"+vw+"' height='"+vh+"'></iframe>");
}

EDIT:
calling the render url at bidding time would allow timing attacks so personally I don't see another solution than providing those URLs upfront.
What is also missing is some of how-to guide for standard problems. One could for example create an enum with all supported creative sizes, lets say there are 15 formats, and then Chrone calls the render url 15 times with all creative sizes upfront. Which means the buyer only needs to specifiy one url but needs to know which sizes to expect.

@sashagavrilov
Copy link

I’m sorry, I haven’t looked in to the capabilities of fenced frames yet. Is it possible to get access to its dimension attributes via JS or CSS from inside as in regular iframe? If this is possible, why wouldn’t you implement responsiveness from the inside of the ad document?

@shivanigithub
Copy link
Contributor

I’m sorry, I haven’t looked in to the capabilities of fenced frames yet. Is it possible to get access to its dimension attributes via JS or CSS from inside as in regular iframe? If this is possible, why wouldn’t you implement responsiveness from the inside of the ad document?

The fenced frame is able to access its own dimensions as a regular iframe.

@fhoering
Copy link
Contributor

OK. Indeed. If the size is available from inside the fenced frame we could migrate the logic client side with JS/CSS in the long run.

@samdutton
Copy link
Contributor

adapt the creative response based on the slot-size

I know this doesn't answer your question, but is it possible to use responsive techniques for asset selection and layout to enable a single render_url to cover multiple slot sizes — or is that just not workable?

@tylerdev0
Copy link
Author

adapt the creative response based on the slot-size

I know this doesn't answer your question, but is it possible to use responsive techniques for asset selection and layout to enable a single render_url to cover multiple slot sizes — or is that just not workable?

This doesn't fit our current use-case and it would require significant re-work throughout our ad-stack in order for something like this to work. Currently we depend on the creative size to be present in the url in order to know which version of the creative to return.

@michaelkleber
Copy link
Collaborator

If nothing else, @tylerdev0, you could have each view URL include "&dim=unknown", and in response to seeing such a URL you could serve a piece of JS which measured the width and height of the window it was in, and then navigated itself to the same URL with the dimensions filled in properly.

This would of course take one extra round-trip between the browser and the server, so I see the efficiency gain from including the size via macro expansion. But if the goal is a proof-of-concept working within the currently-running system, it seems like this would get you there, right?

@tylerdev0
Copy link
Author

@michaelkleber That is an interesting idea; I think we could test something like this for the purposes of the origin trial.
That being said it would be nice to see some native support for this use-case in FLEDGE. I imagine that this is a fairly common issue for ad-techs and it would be great to see this addressed through the FLEDGE spec rather than requiring each ad-tech to develop a bespoke solution to this problem.

@fhoering
Copy link
Contributor

The fenced frame is able to access its own dimensions as a regular iframe.

@shivanigithub What would be the JS APIs to retrieve the width and height from inside a fenced frame ? I tried document.documentElement.clientWidth and window.innerWidth but they both seem to send 0.

@shivanigithub
Copy link
Contributor

@fhoering Both document.documentElement.clientWidth and window.innerWidth are returning non-0 values for me inside a fenced frame. Can you check that the FF is created and navigated successfully: the required Chrome flags are enabled: FencedFrames and PrivacySandboxAdsAPIsOverride and the document loaded inside the FF has the correct supports-loading-mode:fenced-frame response header?

@shivanigithub
Copy link
Contributor

@fhoering Followed this up further within the team (cc @gtanzer ) and it seems there is a time lag between the creation of the FF element and the point at which innerWidth starts returning the actual size (this may not be fenced frames specific though). Once the fenced frame document is rendered on the screen, the APIs should reflect the actual size. Any time lag because of this will be hopefully resolved with the proposal in #312

@fhoering
Copy link
Contributor

OK. Thanks for having a look @shivanigithub

I tried again with some real ad and the script below in latest Chrome Beta. It actually seems to work.

function buildFullCasperUrl(url, w, h) {
    return url + "&width=" + w + "&height=" + h;
}

function invoke(url) {
    const vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0);
    const vh = Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0);
    const fullUrl = buildFullCasperUrl(url, vw, vh);
    document.write("<iframe frameborder='0' scrolling='no' src='"+fullUrl+"' width='"+vw+"' height='"+vh+"'></iframe>");
}
invoke("https://fledge.criteo.com/delivery/direct-rendering?campaignId=282015&bannerId=11032501");

The rendering seems not be be exactly the same however iframe vs fencedframe. I there a way to deactivate the border and scroll ?
See example here: https://tourmaline-ambitious-balaur.glitch.me/

@shivanigithub
Copy link
Contributor

The rendering seems not be be exactly the same however iframe vs fencedframe. I there a way to deactivate the border and scroll ? See example here: https://tourmaline-ambitious-balaur.glitch.me/

Yes, you can add border: none style for the fencedframe element and overflow:hidden style on the inner document as given below:

<fencedframe ... style="border: none">
and
<html lang="en" style="overflow:hidden">

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Non-breaking Feature Request Feature request for functionality unlikely to break backwards compatibility
Projects
None yet
Development

No branches or pull requests

7 participants