How we’re helping New Zealand’s publishers succeed online in 2025

Image: BusinessDesk utilised Subscribe with Google to boost paid subscribers


We’re sharing the programmes we’ve rolled out to support New Zealand’s news publishers succeed online.


As the New Zealand news industry continues to evolve, Google is working to support Kiwi journalists and news organisations of all sizes to respond to the changing way people are looking for and consuming information online. 


Google Search and Google News helps our publishers connect with a local and global audience looking for news content, and the Google News Initiative (GNI) is our decades-long effort to help news publishers navigate this inflection point. 


Whether it's by helping Kiwi publishers connect with audiences, build new business models on digital platforms, or improve productivity through innovative tools and products, many New Zealand publishers have participated in valuable Google-sponsored (free) programs.


Google News Showcase


Since our launch of Google News Showcase in 2022 we’re the only digital platform with commercial agreements, and over 95% of eligible news publishers have signed ongoing partnerships. Representing over 50 different publications, titles include Stuff, TVNZ, NZME, RNZ, Whakaata Māori, The Spinoff and Allied Press, as well as local and regional publishers like Times Online and The Ashburton Guardian.


AI Powering Journalism


Pinpoint, Google’s AI research tool, has enabled TVNZ to digitise its physical archive of over 700,000 newspaper clippings. Previously difficult to access, this collection of New Zealand history from the 1960s onward is now instantly searchable for all staff. With funding from Google, the articles were scanned and uploaded to Pinpoint, allowing journalists to easily fact-check and uncover new stories. Similarly, the digital publisher Crux used the tool to analyze a large volume of documents and uncover critical information for its investigation into the Queenstown Lakeview development.


Evolving Business Models


We have collaborated with news publishers to identify key business challenges and then applied strategic Google support to find solutions. Examples include:


Our latest case studies underline our ongoing support for diverse audiences. We helped Whakaata Māori to rebuild the Te Ao Māori News App, NZME to enhance audience engagement on NZ Herald online and build subscription revenue, and Stuff to adopt a data lead user needs framework to guide content commissioning. 


Google is delivering a tailored one to one consultation and implementation program in 2025 with the News Consumer Insights - Fundamentals/SHIFT. We’re helping nine of Aotearoa’s diverse news organisations generate more value from their readers by improving engagement and retention, as well as creating a pathway to digital subscriptions and increased advertising revenue. 


Subscribing With Google


To diversify revenue streams and help news publishers improve financial sustainability beyond advertising, Subscribe with Google is a tool to identify likely subscribers and grow subscriber bases.

This simple way to subscribe to news publications and maintain access everywhere has helped two of New Zealand’s largest publishers:


  • Stuff, Joanna Norris, Managing Director - Stuff Masthead Publishing: “Over the past year, our partnership with Subscribe with Google has supported our digital subscriber acquisition strategy. We’ve been able to streamline our subscription journey and reduce friction, enabling more seamless, user-friendly subscription experiences across ThePost.co.nz, ThePress.co.nz, and WaikatoTimes.co.nz. Google’s technical expertise has helped us scale quickly and deliver digital growth. This collaboration accelerated our subscription growth, which is up approximately 628% year-on-year for users subscribing via the Google Play Store.”

  • NZME, Carolyn Luey, Chief Digital & Publishing Officer: “Subscribe with Google is available on the NZ Herald website as a quick, simple way for new subscribers to purchase the New Zealand Herald premium subscription. Funded by Google through our partnership, it was easy to implement on the site and gives us another way to make it easier for potential subscribers to pay for the content they want to read.”


Optimising for YouTube


The YouTube Audience Lab has been designed to equip small-to-medium news publishers, digital-first news channels and news creators/journalists producing public interest journalism with the information, tools and practical support to grow their audience and optimise their news content on YouTube. Facilitated by proven leaders in news programs for YouTube, Changer, this program has been offered free of charge to four NZ news organisations - The Ashburton Guardian, The Spinoff, Pacific Media Network and Pasifika TV.


Proven News Publisher Strategies


Partnering with the Financial Times Strategies, GNI rolled out three key programmes to provide business strategy support to New Zealand news organisations. Goals of these programmes were to help business leaders shape and begin to execute a compelling strategic ambition, help publishers at the beginning of their digital reader revenue journey (to identify diverse revenue models and to evolve digital businesses) and audits through the News Sustainability Project. The GNI and FT Strategies have collaborated to build a set of free tools to help publishers on their journey to long-term sustainability readiness. 


Over the past 12 months, 18 New Zealand news organisations have participated in our free Google News Initiative Advertising Lab.  The GA4 Accelerator Program empowered news publishers by providing data-driven tools and strategies to enhance content performance, boost subscriptions, and improve ad performance, ultimately driving business growth. In partnership with Monks, Google offered a series of five interactive webinars for 15 news publishers across New Zealand. Eligible news publishers also received free personalised one to one consultation sessions, receiving dedicated support.


With only half the year done, we’re looking forward to continuing to collaborate with Aotearoa’s news publishers to ensure they’re equipped with the tools and resources that are needed to succeed online.



Post content

What’s new in the Jetpack Compose August ’25 release

Posted by Meghan Mehta – Developer Relations Engineer and Nick Butcher – Product Manager

Today, the Jetpack Compose August ‘25 release is stable. This release contains version 1.9 of core compose modules (see the full BOM mapping), introducing new APIs for rendering shadows, 2D scrolling, rich styling of text transformations, improved list performance, and more!

To use today’s release, upgrade your Compose BOM version to 2025.08.00:

implementation(platform("androidx.compose:compose-bom:2025.08.00"))

Shadows

We're happy to introduce two highly requested modifiers: Modifier.dropShadow() and Modifier.innerShadow() allowing you to render box-shadow effects (compared to the existing Modifier.shadow() which renders elevation based shadows based on a lighting model).

Modifier.dropShadow()

The dropShadow() modifier draws a shadow behind your content. You can add it to your composable chain and specify the radius, color, and spread. Remember, content that should appear on top of the shadow (like a background) should be drawn after the dropShadow() modifier.

@Composable
@Preview(showBackground = true)
fun SimpleDropShadowUsage() {
    val pinkColor = Color(0xFFe91e63)
    val purpleColor = Color(0xFF9c27b0)
    Box(Modifier.fillMaxSize()) {
        Box(
            Modifier
                .size(200.dp)
                .align(Alignment.Center)
                .dropShadow(
                    RoundedCornerShape(20.dp),
                    dropShadow = DropShadow(
                        15.dp,
                        color = pinkColor,
                        spread = 10.dp,
                        alpha = 0.5f
                    )
                )
                .background(
                    purpleColor,
                    shape = RoundedCornerShape(20.dp)
                )
        )
    }
}
drop shadow drawn all around shape
Figure 1. Drop shadow drawn all around shape

Modifier.innerShadow()

The Modifier.innerShadow() draws shadows on the inset of the provided shape:

@Composable
@Preview(showBackground = true)
fun SimpleInnerShadowUsage() {
    val pinkColor = Color(0xFFe91e63)
    val purpleColor = Color(0xFF9c27b0)
    Box(Modifier.fillMaxSize()) {
        Box(
            Modifier
                .size(200.dp)
                .align(Alignment.Center)
                .background(
                    purpleColor,
                    shape = RoundedCornerShape(20.dp)
                )
                .innerShadow(
                    RoundedCornerShape(20.dp),
                    innerShadow = InnerShadow(
                        15.dp,
                        color = Color.Black,
                        spread = 10.dp,
                        alpha = 0.5f
                    )
                )
        )
    }
}
modifier.innerShadow() applied to a shape
Figure 2. Modifier.innerShadow() applied to a shape

The order for inner shadows is very important. The inner shadow draws on top of the content, so for the example above, we needed to move the inner shadow modifier after the background modifier. We’d need to do something similar when using it on top of something like an Image. In this example, we’ve placed a separate Box to render the shadow in the layer above the image:

@Composable
@Preview(showBackground = true)
fun PhotoInnerShadowExample() {
    Box(Modifier.fillMaxSize()) {
        val shape = RoundedCornerShape(20.dp)
        Box(
            Modifier
                .size(200.dp)
                .align(Alignment.Center)
        ) {
            Image(
                painter = painterResource(id = R.drawable.cape_town),
                contentDescription = "Image with Inner Shadow",
                contentScale = ContentScale.Crop,
                modifier = Modifier.fillMaxSize()
                    .clip(shape)
            )
            Box(
                modifier = Modifier.fillMaxSize()
                    .innerShadow(
                        shape,
                        innerShadow = InnerShadow(15.dp,
                            spread = 15.dp)
                    )
            )
        }
    }
}
Inner shadow on top of an image
Figure 3.Inner shadow on top of an image

New Visibility modifiers

Compose UI 1.8 introduced onLayoutRectChanged, a new performant way to track the location of elements on screen. We're building on top of this API to support common use cases by introducing onVisibilityChanged and onFirstVisible. These APIs accept optional parameters for the minimum fraction or amount of time the item has been visible for before invoking your action.

Use onVisibilityChanged for UI changes or side effects that should happen based on visibility, like automatically playing and pausing videos or starting an animation:

LazyColumn {
  items(feedData) { video ->
    VideoRow(
        video,
        Modifier.onVisibilityChanged(minDurationMs = 500, minFractionVisible = 1f) {
          visible ->
            if (visible) video.play() else video.pause()
          },
    )
  }
}

Use onFirstVisible for use cases when you wish to react to an element first becoming visible on screen for example to log impressions:

LazyColumn {
    items(100) {
        Box(
            Modifier
                // Log impressions when item has been visible for 500ms
                .onFirstVisible(minDurationMs = 500) { /* log impression */ }
                .clip(RoundedCornerShape(16.dp))
                .drawBehind { drawRect(backgroundColor) }
                .fillMaxWidth()
                .height(100.dp)
        )
    }
}

Rich styling in OutputTransformation

BasicTextField now supports applying styles like color and font weight from within an OutputTransformation.

The new TextFieldBuffer.addStyle() methods let you apply a SpanStyle or ParagraphStyle to change the appearance of text, without changing the underlying TextFieldState. This is useful for visually formatting input, like phone numbers or credit cards. This method can only be called inside an OutputTransformation.

// Format a phone number and color the punctuation
val phoneTransformation = OutputTransformation {
    // 1234567890 -> (123) 456-7890
    if (length == 10) {
        insert(0, "(")
        insert(4, ") ")
        insert(9, "-")

        // Color the added punctuation
        val gray = Color(0xFF666666)
        addStyle(SpanStyle(color = gray), 0, 1)
        addStyle(SpanStyle(color = gray), 4, 5)
        addStyle(SpanStyle(color = gray), 9, 10)
    }
}

BasicTextField(
    state = myTextFieldState,
    outputTransformation = phoneTransformation
)

LazyLayout

The building blocks of LazyLayout are all now stable! Check out LazyLayoutMeasurePolicy, LazyLayoutItemProvider, and LazyLayoutPrefetchState to build your own Lazy components.

Prefetch Improvements

There are now significant scroll performance improvements in Lazy List and Lazy Grid with the introduction of new prefetch behavior. You can now define a LazyLayoutCacheWindow to prefetch more content. By default, only one item is composed ahead of time in the direction of scrolling, and after something scrolls off screen it is discarded. You can now customize the amount of items ahead to prefetch and behind to retain through a fraction of the viewport or dp size. When you opt into using LazyLayoutCacheWindow, items begin prefetching in the ahead area straight away.

The configuration entry point for this is on LazyListState, which takes in the cache window size:

@OptIn(ExperimentalFoundationApi::class)
@Composable
private fun LazyColumnCacheWindowDemo() {
    // Prefetch items 150.dp ahead and retain items 100.dp behind the visible viewport
    val dpCacheWindow = LazyLayoutCacheWindow(ahead = 150.dp, behind = 100.dp)
    // Alternatively, prefetch/retain items as a fraction of the list size
    // val fractionCacheWindow = LazyLayoutCacheWindow(aheadFraction = 1f, behindFraction = 0.5f)
    val state = rememberLazyListState(cacheWindow = dpCacheWindow)
    LazyColumn(state = state) {
        items(1000) { Text(text = "$it", fontSize = 80.sp) }
    }
}
lazylayout in Compose 1.9 release
Note: Prefetch composes more items than are currently visible — the new cache window API will likely increase prefetching. This means that item's LaunchedEffects and DisposableEffects may run earlier – do not use this as a signal for visibility e.g. for impression tracking. Instead, we recommend using the new onFirstVisible and onVisibilityChanged APIs. Even if you're not manually customizing LazyLayoutCacheWindow now, avoid using composition effects as a signal of content visibility, as this new prefetch mechanism will be enabled by default in a future release.

Scroll

2D Scroll APIs

Following the release of Draggable2D, Scrollable2D is now available, bringing two-dimensional scrolling to Compose. While the existing Scrollable modifier handles single-orientation scrolling, Scrollable2D enables both scrolling and flinging in 2D. This allows you to create more complex layouts that move in all directions, such as spreadsheets or image viewers. Nested scrolling is also supported, accommodating 2D scenarios.

val offset = remember { mutableStateOf(Offset.Zero) }
Box(
    Modifier.size(150.dp)
        .scrollable2D(
            state =
                rememberScrollable2DState { delta ->
                    offset.value = offset.value + delta // update the state
                    delta // indicate that we consumed all the pixels available
                }
        )
        .background(Color.LightGray),
    contentAlignment = Alignment.Center,
) {
    Text(
        "X=${offset.value.x.roundToInt()} Y=${offset.value.y.roundToInt()}",
        style = TextStyle(fontSize = 32.sp),
    )
}
moving image of 2D scroll API demo

Scroll Interop Improvements

There are bug fixes and new features to improve scroll and nested scroll interop with Views, including the following:

    • Fixed the dispatching of incorrect velocities during fling animations between Compose and Views.
    • Compose now correctly invokes the View's nested scroll callbacks in the appropriate order.

Improve crash analysis by adding source info to stack traces

We have heard from you that it can be hard to debug Compose crashes when your own code does not appear in the stack trace. To address this we're providing a new, opt-in API to provide richer crash location details, including composable names and locations enabling you to:

    • Efficiently identify and resolve crash sources.
    • More easily isolate crashes for reproducible samples.
    • Investigate crashes that previously only showed internal stack frames.

Note that we do not recommend using this API in release builds due to the performance impact of collecting this extra information, nor does it work in minified apks.

To enable this feature, add the line below to the application entry point. Ideally, this configuration should be performed before any compositions are created to ensure that the stack trace information is collected:

class App : Application() {
   override fun onCreate() {
        // Enable only for debug flavor to avoid perf regressions in release
        Composer.setDiagnosticStackTraceEnabled(BuildConfig.DEBUG)
   }
}

New annotations and Lint checks

We are introducing a new runtime-annotation library that exposes annotations used by the compiler and tooling (such as lint checks). This allows non-Compose modules to use these annotations without a dependency on the Compose runtime library. The @Stable, @Immutable, and @StableMarker annotations have moved to runtime-annotation, allowing you to annotate classes and functions that do not depend on Compose.

Additionally, we have added two new annotations and corresponding lint checks:

    • @RememberInComposition: An annotation that can mark constructors, functions, and property getters, to indicate that they must not be called directly inside composition without being remembered. Errors will be raised by a corresponding lint check.
    • @FrequentlyChangingValue: An annotation that can mark functions, and property getters, to indicate that they should not be called directly inside composition, as this may cause frequent recompositions (for example, marking scroll position values and animating values). Warnings are provided by a corresponding lint check.

Additional updates

Get started

We appreciate all bug reports and feature requests submitted to our issue tracker. Your feedback allows us to build the APIs you need in your apps. Happy composing!

Adding AI image editing features to Google Slides and Google Vids

What’s changing 

Building upon generative image capabilities across Google Workspace, we’re excited to introduce two AI image editing features in Google Slides and Google Vids. 

To expand on the ability to edit your images, we’re adding the options to modify the background of your image beyond removing the background. Simply select your image, and click on the ‘Generate an image’ icon in the side panel, select ‘Edit’ and select "Replace background." and type in a prompt, such as ‘Minimalist product shot in studio’ and select ‘Create’. This new feature can be useful in numerous scenarios, for example: 
  • Contextualize products: Take a standard product photo (e.g., a chair on a plain background) and instantly place it in a variety of realistic settings like a modern living room, a cozy café, or an outdoor patio to help customers visualize it.
  • Company headshots/team photos: Easily remove distracting backgrounds from employee photos and replace them with a professional, unified backdrop for internal and external presentations (e.g., "Meet the Team" slides, company profiles). 
  • Tailored client presentations: Quickly adapt presentation visuals to resonate with specific clients by changing backgrounds to reflect their industry, location, or company culture. For example, show a software solution being used in a specific office environment or industry setting. 
  • Visually engaging training materials: Create more appealing training slides by replacing generic backgrounds with relevant imagery that helps illustrate concepts (e.g., a customer service representative in a dynamic call center environment). 

Replacing the background of an image in Vids 

Gemini can also now help intelligently expand the background of your images, so you can seamlessly resize and reframe visuals without distortion or compromising quality. For example, if you have a smaller image of an object in your Slides presentation and you’d like to make it bigger to increase its impact, simply open the expand feature using “Generate an image” in the side panel of Slides or the sidebar. From there, you select your desired aspect ratio and can browse different image options to preview before inserting one into your presentation. 

Expanding the background of an image in Slides 


Who’s impacted 

End users 

Why you’d use it 

Editing images with Gemini helps those without design skills meet their imagery needs, and unlocks a new level of flexibility and professionalism for Vids and Slides presentations. 

Getting started 


Rollout pace 


Availability 

Available for Google Workspace: 
  • Business Standard and Plus 
  • Enterprise Standard and Plus 
  • Customers with the Gemini Education or Gemini Education Premium add-on 
  • Google AI Pro and Ultra 
Anyone who previously purchased these legacy add-ons will also receive this feature: 
  • Gemini Business* 
  • Gemini Enterprise* 
*As of January 15, 2025, we’re no longer offering the Gemini Business and Gemini Enterprise add-ons for sale. Please refer to this announcement for more details.