diff --git a/package.json b/package.json
index cfffbdf38..d8cfc5f56 100644
--- a/package.json
+++ b/package.json
@@ -52,6 +52,7 @@
"@babel/preset-react": "7.28.5",
"@mdx-js/mdx": "^2.1.3",
"@resvg/resvg-js": "^2.6.2",
+ "@shuding/opentype.js": "1.4.0-beta.0",
"@types/body-scroll-lock": "^2.6.1",
"@types/classnames": "^2.2.10",
"@types/debounce": "^1.2.1",
diff --git a/public/images/team/gh-robhogan.jpg b/public/images/team/gh-robhogan.jpg
new file mode 100644
index 000000000..4d5a5e830
Binary files /dev/null and b/public/images/team/gh-robhogan.jpg differ
diff --git a/scripts/generateOgImages.mjs b/scripts/generateOgImages.mjs
index 937727a1c..bc805d386 100644
--- a/scripts/generateOgImages.mjs
+++ b/scripts/generateOgImages.mjs
@@ -14,6 +14,7 @@ import path from 'path';
import satori from 'satori';
import {Resvg} from '@resvg/resvg-js';
import matter from 'gray-matter';
+import opentype from '@shuding/opentype.js';
const ROOT = process.cwd();
const CONTENT_DIR = path.join(ROOT, 'src', 'content');
@@ -34,6 +35,33 @@ const medium = fs.readFileSync(
path.join(ROOT, 'public', 'fonts', 'Optimistic_Display_W_Md.ttf')
);
+// Title area width: card width minus the horizontal padding (80px per side).
+const TITLE_MAX_WIDTH = 1200 - 80 * 2;
+const TITLE_MAX_FONT = 96;
+const TITLE_MIN_FONT = 56;
+// Small margin so borderline titles don't wrap and orphan a single trailing
+// character (e.g. the "p" in "renderToStaticMarkup", which is 1px too wide
+// to fit on one line at 96px).
+const TITLE_SAFETY = 8;
+
+const boldFont = opentype.parse(
+ bold.buffer.slice(bold.byteOffset, bold.byteOffset + bold.byteLength)
+);
+
+// Multi-word titles wrap cleanly at spaces, so a length bucket is fine for
+// them. Single-word titles (most API names) can only break mid-word, which
+// leaves an orphaned letter on its own line, so instead shrink them just
+// enough to fit on a single line.
+function titleFontSize(title) {
+ const trimmed = title.trim();
+ if (/\s/.test(trimmed)) {
+ return trimmed.length > 24 ? 72 : 96;
+ }
+ const widthPerPx = boldFont.getAdvanceWidth(trimmed, 1);
+ const fit = Math.floor((TITLE_MAX_WIDTH - TITLE_SAFETY) / widthPerPx);
+ return Math.max(TITLE_MIN_FONT, Math.min(TITLE_MAX_FONT, fit));
+}
+
function el(type, style, children) {
return {type, props: {style, children}};
}
@@ -103,7 +131,7 @@ function card(title, pagePath) {
flexGrow: 1,
display: 'flex',
alignItems: 'center',
- fontSize: title.length > 24 ? 72 : 96,
+ fontSize: titleFontSize(title),
fontFamily: 'Optimistic Display Bold',
color: '#f6f7f9',
lineHeight: 1.1,
diff --git a/src/content/community/team.md b/src/content/community/team.md
index e321f240b..dd77a539e 100644
--- a/src/content/community/team.md
+++ b/src/content/community/team.md
@@ -26,7 +26,7 @@ React work is organized into working groups, each responsible for an area of the
-
+
Ricky majored in theoretical math and somehow found himself on the React Native team for a couple years before joining the React team. When he's not programming you can find him snowboarding, biking, climbing, golfing, or closing GitHub issues that do not match the issue template.
@@ -38,7 +38,7 @@ React work is organized into working groups, each responsible for an area of the
## Working Group members {/*working-group-members*/}
-
+
@@ -82,11 +82,11 @@ React work is organized into working groups, each responsible for an area of the
-
+
-
+
-
+
Ruslan's introduction to UI programming started when he was a kid by manually editing HTML templates for his custom gaming forums. Somehow, he ended up majoring in Computer Science. He enjoys music, games, and memes. Mostly memes.
diff --git a/src/content/learn/tutorial-tic-tac-toe.md b/src/content/learn/tutorial-tic-tac-toe.md
index c7dd0e7f4..ee26ecafb 100644
--- a/src/content/learn/tutorial-tic-tac-toe.md
+++ b/src/content/learn/tutorial-tic-tac-toe.md
@@ -901,11 +901,11 @@ body {
React Developer Tools, React component’lerinizin props ve state’ini kontrol etmenizi sağlar. [Chrome](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en), [Firefox](https://addons.mozilla.org/en-US/firefox/addon/react-devtools/) ve [Edge](https://microsoftedge.microsoft.com/addons/detail/react-developer-tools/gpphkfbcpidddadnkolkpfckpihlkkil) browser extension olarak kullanılabilir.
-Yükledikten sonra, React kullanan siteler için browser Developer Tools içinde yeni bir *Components* tab’ı görünür. CodeSandbox’ta takip ediyorsanız, önce sandbox preview’unuzu yeni bir tab’da açmanız gerekir:
+Yükledikten sonra, React kullanan siteler için browser Developer Tools içinde yeni bir **Components** tab’ı görünür. CodeSandbox’ta takip ediyorsanız, önce sandbox preview’unuzu yeni bir tab’da açmanız gerekir:

-Ardından preview sayfasında browser’ınızın DevTools’unu açın ve *Components* tab’ını bulun:
+Ardından preview sayfasında browser’ınızın DevTools’unu açın ve **Components** tab’ını bulun:

diff --git a/src/content/reference/react/Suspense.md b/src/content/reference/react/Suspense.md
index 87641eef6..c2602da94 100644
--- a/src/content/reference/react/Suspense.md
+++ b/src/content/reference/react/Suspense.md
@@ -37,6 +37,14 @@ title:
- React, Suspense ile entegre olan **Streaming Server Rendering** ve **Selective Hydration** gibi under-the-hood optimizasyonlar içerir. Daha fazla bilgi edinmek için [mimari overview](https://github.com/reactwg/react-18/discussions/37) okuyun ve [teknik konuşmayı](https://www.youtube.com/watch?v=pj5N-Khihgc) izleyin.
- React, Suspense ile entegre olan **Streaming Server Rendering** ve **Selective Hydration** gibi under-the-hood optimizasyonlar içerir. Daha fazla bilgi edinmek için [mimari overview](https://github.com/reactwg/react-18/discussions/37) okuyun ve [teknik konuşmayı](https://www.youtube.com/watch?v=pj5N-Khihgc) izleyin.
+- Suspense, data’nın bir Effect veya event handler içinde fetch edildiğini detect etmez. Yalnızca [aşağıda listelenen durumlarda](#what-activates-a-suspense-boundary) aktive olur.
+- React, ilk kez mount olamadan önce suspend olan render’lar için hiçbir state’i preserve etmez. Component yüklendiğinde, React suspended tree’yi sıfırdan yeniden render etmeyi dener.
+- Suspense tree için content gösteriyorken tree tekrar suspend olursa, buna neden olan update [`startTransition`](/reference/react/startTransition) veya [`useDeferredValue`](/reference/react/useDeferredValue) tarafından oluşturulmadığı sürece `fallback` tekrar gösterilir.
+- React, suspended content’i son reveal’dan itibaren ölçülen en fazla 300ms’de bir reveal eder. Bu pencere içinde ready olan boundary’ler tek tek değil, [birlikte reveal edilir](/blog/2025/10/01/react-19-2#batching-suspense-boundaries-for-ssr).
+- React, tekrar suspend olduğu için zaten visible olan content’i hide etmek zorunda kalırsa, content tree içindeki [layout Effects](/reference/react/useLayoutEffect)’leri cleanup eder. Content tekrar gösterilmeye hazır olduğunda, React layout Effects’i tekrar çalıştırır. Bu, DOM layout’unu ölçen Effects’in content hidden durumdayken bunu yapmaya çalışmamasını sağlar.
+- React includes under-the-hood optimizations like *Streaming Server Rendering* and *Selective Hydration* that are integrated with Suspense. Read [an architectural overview](https://github.com/reactwg/react-18/discussions/37) and watch [a technical talk](https://www.youtube.com/watch?v=pj5N-Khihgc) to learn more.
+- React *Server Render'ını Stream etme* ve *Selektif Hydrate Etme* gibi Suspense ile entegre olan altta yatan optimizasyonlar içerir. Daha fazla bilgi almak için [mimari bir bakışı](https://github.com/reactwg/react-18/discussions/37) okuyun ve [teknik bir konuşmayı](https://www.youtube.com/watch?v=pj5N-Khihgc) izleyin.
+
---
### Suspense boundary’yi ne aktive eder? {/*what-activates-a-suspense-boundary*/}
@@ -49,16 +57,15 @@ Bir Suspense boundary, content’ini reveal etmeden önce onun hazır olmasını
- Streaming server rendering sırasında büyük bir boundary’nin HTML’inin gelmesini beklemek. HTML göndermek zaman alır; bu yüzden yeterince content içeren bir boundary, içinde hiçbir şey suspend olmasa bile aktive olur. React, HTML geldikçe content’i reveal eder.
- Font yüklemek. Suspense default olarak font’ları beklemez, ancak bir [``](/reference/react/ViewTransition) update’i, text’in fallback font ile flash etmemesi için yeni font’ların yüklenmesini bir timeout’a kadar bekler. [Aşağıdaki örneğe bakın.](#waiting-for-a-font-to-load)
- Image yüklemek. Suspense default olarak image’ları beklemez, ancak bir [``](/reference/react/ViewTransition) update’i sırasında React, image yüklenene kadar, bir timeout’a kadar boundary’yi block eder. `onLoad` handler eklemek belirli bir image’ı bu davranışın dışına çıkarır. [Aşağıdaki örneğe bakın.](#waiting-for-an-image-to-load)
-
- Bir [``](#props) boundary’si içinde CPU-bound render work gerçekleştirmek.
#### Suspense-enabled frameworks {/*suspense-enabled-frameworks*/}
-A *Suspense-enabled framework* gives you a way to read data in your component in a way that activates the closest Suspense boundary. The exact way you load your data depends on your framework, and you'll find the details in its documentation. Under the hood, a Suspense-enabled framework maintains a cache of Promises and calls [`use`](/reference/react/use) to suspend on a Promise.
+Bir **Suspense-enabled framework**, component’inizde data’yı en yakın Suspense boundary’yi aktive edecek şekilde okumanız için bir yol sağlar. Data’nızı tam olarak nasıl load edeceğiniz framework’ünüze bağlıdır ve detayları onun documentation’ında bulursunuz. Under the hood, Suspense-enabled bir framework Promise’lerden oluşan bir cache tutar ve bir Promise üzerinde suspend olmak için [`use`](/reference/react/use) çağırır.
-Without a framework, you can read a Promise with `use` directly, as long as the Promise is [cached so the same instance is reused across renders.](/reference/react/use#caching-promises-for-client-components)
+Framework olmadan, Promise [render’lar arasında aynı instance yeniden kullanılacak şekilde cache’lendiği](/reference/react/use#caching-promises-for-client-components) sürece doğrudan `use` ile bir Promise okuyabilirsiniz.
diff --git a/src/content/reference/react/useDeferredValue.md b/src/content/reference/react/useDeferredValue.md
index d7d342c86..def4767fe 100644
--- a/src/content/reference/react/useDeferredValue.md
+++ b/src/content/reference/react/useDeferredValue.md
@@ -88,7 +88,7 @@ Güncellemeler esnasında, ertelenmiş değer en s
Bu örnek, [`use`](/reference/react/use) ile okuduğunuz bir Promise gibi, [Suspense boundary’yi aktive eden](/reference/react/Suspense#what-activates-a-suspense-boundary) bir data source kullandığınızı varsayar.
-[Suspense ve sınırlamaları hakkında daha fazla bilgi edinin.](/reference/react/Suspense)
+[Suspense hakkında daha fazla bilgi edinin.](/reference/react/Suspense)
diff --git a/yarn.lock b/yarn.lock
index c25a25421..2808d8c8d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3429,6 +3429,7 @@ eslint-plugin-jsx-a11y@^6.4.1:
"eslint-plugin-local-rules@link:eslint-local-rules":
version "0.0.0"
+ uid ""
eslint-plugin-react-compiler@^19.0.0-beta-e552027-20250112:
version "19.0.0-beta-e552027-20250112"