Skip to content

Commit 20ddc20

Browse files
committed
Refactor Next.js integration
1 parent 97d0d1c commit 20ddc20

File tree

6 files changed

+308
-152
lines changed

6 files changed

+308
-152
lines changed

crates/common/src/html_processor.rs

Lines changed: 27 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use std::cell::Cell;
55
use std::rc::Rc;
66

77
use lol_html::{element, html_content::ContentType, text, Settings as RewriterSettings};
8-
use regex::Regex;
98

109
use crate::integrations::{
1110
AttributeRewriteOutcome, IntegrationAttributeContext, IntegrationRegistry,
@@ -22,14 +21,12 @@ pub struct HtmlProcessorConfig {
2221
pub request_host: String,
2322
pub request_scheme: String,
2423
pub integrations: IntegrationRegistry,
25-
pub nextjs_enabled: bool,
26-
pub nextjs_attributes: Vec<String>,
2724
}
2825

2926
impl HtmlProcessorConfig {
3027
/// Create from settings and request parameters
3128
pub fn from_settings(
32-
settings: &Settings,
29+
_settings: &Settings,
3330
integrations: &IntegrationRegistry,
3431
origin_host: &str,
3532
request_host: &str,
@@ -40,8 +37,6 @@ impl HtmlProcessorConfig {
4037
request_host: request_host.to_string(),
4138
request_scheme: request_scheme.to_string(),
4239
integrations: integrations.clone(),
43-
nextjs_enabled: settings.publisher.nextjs.enabled,
44-
nextjs_attributes: settings.publisher.nextjs.rewrite_attributes.clone(),
4540
}
4641
}
4742
}
@@ -75,39 +70,6 @@ pub fn create_html_processor(config: HtmlProcessorConfig) -> impl StreamProcesso
7570
fn protocol_relative_replacement(&self) -> String {
7671
format!("//{}", self.request_host)
7772
}
78-
79-
fn rewrite_nextjs_values(&self, content: &str, attributes: &[String]) -> Option<String> {
80-
let mut rewritten = content.to_string();
81-
let mut changed = false;
82-
let escaped_origin = regex::escape(&self.origin_host);
83-
for attribute in attributes {
84-
let escaped_attr = regex::escape(attribute);
85-
let pattern = format!(
86-
r#"(?P<prefix>(?:\\*")?{attr}(?:\\*")?:\\*")(?P<scheme>https?://|//){origin}"#,
87-
attr = escaped_attr,
88-
origin = escaped_origin
89-
);
90-
let regex = Regex::new(&pattern).expect("valid Next.js rewrite regex");
91-
let new_value = regex.replace_all(&rewritten, |caps: &regex::Captures| {
92-
let scheme = &caps["scheme"];
93-
let replacement = if scheme == "//" {
94-
format!("//{}", self.request_host)
95-
} else {
96-
self.replacement_url()
97-
};
98-
format!("{}{}", &caps["prefix"], replacement)
99-
});
100-
if new_value != rewritten {
101-
changed = true;
102-
rewritten = new_value.into_owned();
103-
}
104-
}
105-
if changed {
106-
Some(rewritten)
107-
} else {
108-
None
109-
}
110-
}
11173
}
11274

11375
let patterns = Rc::new(UrlPatterns {
@@ -116,8 +78,6 @@ pub fn create_html_processor(config: HtmlProcessorConfig) -> impl StreamProcesso
11678
request_scheme: config.request_scheme.clone(),
11779
});
11880

119-
let nextjs_attributes = Rc::new(config.nextjs_attributes.clone());
120-
12181
let injected_tsjs = Rc::new(Cell::new(false));
12282
let integration_registry = config.integrations.clone();
12383
let script_rewriters = integration_registry.script_rewriters();
@@ -378,35 +338,6 @@ pub fn create_html_processor(config: HtmlProcessorConfig) -> impl StreamProcesso
378338
}));
379339
}
380340

381-
if config.nextjs_enabled && !nextjs_attributes.is_empty() {
382-
element_content_handlers.push(text!("script#__NEXT_DATA__", {
383-
let patterns = patterns.clone();
384-
let attributes = nextjs_attributes.clone();
385-
move |text| {
386-
let content = text.as_str();
387-
if let Some(rewritten) = patterns.rewrite_nextjs_values(content, &attributes) {
388-
text.replace(&rewritten, ContentType::Text);
389-
}
390-
Ok(())
391-
}
392-
}));
393-
394-
element_content_handlers.push(text!("script", {
395-
let patterns = patterns.clone();
396-
let attributes = nextjs_attributes.clone();
397-
move |text| {
398-
let content = text.as_str();
399-
if !content.contains("self.__next_f") {
400-
return Ok(());
401-
}
402-
if let Some(rewritten) = patterns.rewrite_nextjs_values(content, &attributes) {
403-
text.replace(&rewritten, ContentType::Text);
404-
}
405-
Ok(())
406-
}
407-
}));
408-
}
409-
410341
let rewriter_settings = RewriterSettings {
411342
element_content_handlers,
412343
..RewriterSettings::default()
@@ -433,8 +364,6 @@ mod tests {
433364
request_host: "test.example.com".to_string(),
434365
request_scheme: "https".to_string(),
435366
integrations: IntegrationRegistry::default(),
436-
nextjs_enabled: false,
437-
nextjs_attributes: vec!["href".to_string(), "link".to_string(), "url".to_string()],
438367
}
439368
}
440369

@@ -605,9 +534,19 @@ mod tests {
605534
</script>
606535
</body></html>"#;
607536

608-
let mut config = create_test_config();
609-
config.nextjs_enabled = true;
610-
config.nextjs_attributes = vec!["href".to_string(), "link".to_string(), "url".to_string()];
537+
let mut settings = create_test_settings();
538+
settings
539+
.integrations
540+
.insert_config(
541+
"nextjs",
542+
&json!({
543+
"enabled": true,
544+
"rewrite_attributes": ["href", "link", "url"],
545+
}),
546+
)
547+
.expect("should update nextjs config");
548+
let registry = IntegrationRegistry::new(&settings);
549+
let config = config_from_settings(&settings, &registry);
611550
let processor = create_html_processor(config);
612551
let pipeline_config = PipelineConfig {
613552
input_compression: Compression::None,
@@ -659,9 +598,19 @@ mod tests {
659598
</script>
660599
</body></html>"#;
661600

662-
let mut config = create_test_config();
663-
config.nextjs_enabled = true;
664-
config.nextjs_attributes = vec!["href".to_string(), "link".to_string(), "url".to_string()];
601+
let mut settings = create_test_settings();
602+
settings
603+
.integrations
604+
.insert_config(
605+
"nextjs",
606+
&json!({
607+
"enabled": true,
608+
"rewrite_attributes": ["href", "link", "url"],
609+
}),
610+
)
611+
.expect("should update nextjs config");
612+
let registry = IntegrationRegistry::new(&settings);
613+
let config = config_from_settings(&settings, &registry);
665614
let processor = create_html_processor(config);
666615
let pipeline_config = PipelineConfig {
667616
input_compression: Compression::None,
@@ -774,15 +723,6 @@ mod tests {
774723
assert_eq!(config.origin_host, "origin.test-publisher.com");
775724
assert_eq!(config.request_host, "proxy.example.com");
776725
assert_eq!(config.request_scheme, "https");
777-
assert!(
778-
!config.nextjs_enabled,
779-
"Next.js rewrites should default to disabled"
780-
);
781-
assert_eq!(
782-
config.nextjs_attributes,
783-
vec!["href".to_string(), "link".to_string(), "url".to_string()],
784-
"Should default to rewriting href/link/url attributes"
785-
);
786726
}
787727

788728
#[test]

crates/common/src/integrations/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
33
use crate::settings::Settings;
44

5+
pub mod nextjs;
56
pub mod prebid;
67
mod registry;
78
pub mod testlight;
@@ -16,5 +17,5 @@ pub use registry::{
1617
type IntegrationBuilder = fn(&Settings) -> Option<IntegrationRegistration>;
1718

1819
pub(crate) fn builders() -> &'static [IntegrationBuilder] {
19-
&[prebid::register, testlight::register]
20+
&[prebid::register, testlight::register, nextjs::register]
2021
}

0 commit comments

Comments
 (0)