Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
bf1023d
feat(arabic): initialize Arabic translation
RlxChap2 May 19, 2026
e7ae69e
docs(configuration): translate configuration pages
RlxChap2 May 19, 2026
388f553
docs(configuration): edited language terms
RlxChap2 May 19, 2026
8c74c7d
docs(ar): add final newlines
RlxChap2 May 20, 2026
6536001
docs(concept): translated concepts files
RlxChap2 May 20, 2026
917c693
Merge branch 'main' of https://github.com/RlxChap2/webpack.js.org
RlxChap2 May 20, 2026
2b1905a
docs(ar): changing layout from ltr to rtl
RlxChap2 May 21, 2026
4a205de
feat(guides): guides arabic translation
arabpolice May 21, 2026
a8fd007
docs(guides): add contributors to getting started and index guides
RlxChap2 May 21, 2026
a7219db
docs(ar): fix MDX lint issues
RlxChap2 May 22, 2026
505b187
feat(i18n): add language switcher
RlxChap2 May 22, 2026
b28ccc1
fix(ar): decode hash anchors
RlxChap2 May 22, 2026
6cdae05
test(e2e): update Arabic assertions
RlxChap2 May 22, 2026
cf426c0
fix(ar): encode heading anchors
RlxChap2 May 22, 2026
6dd7172
docs(ar): fix links and lint
RlxChap2 May 22, 2026
46c72a3
docs(ar): fix config lint issues
RlxChap2 May 22, 2026
65067c1
docs(ar): format remaining config tables
RlxChap2 May 22, 2026
d4b6bd6
docs(ar): fix asset guide lint
RlxChap2 May 22, 2026
23cacbd
docs(ar): fix guide lint issues
RlxChap2 May 22, 2026
0f1c594
fix(ar): lint site config module
RlxChap2 May 22, 2026
7c89635
docs(contribute): translated contribute docs
semon009 May 24, 2026
c87160f
docs: ar translation for plugins
MohaDev-69 May 25, 2026
556ccb1
feat: add plugin documentations
MohaDev-69 May 25, 2026
cf46228
feat: add documentation for plugins
MohaDev-69 May 25, 2026
70b6b0d
docs(api): translate api docs content
RlxChap2 Jun 9, 2026
c602c28
docs(configuration): fixed translation in resolve.mdx
RlxChap2 Jun 9, 2026
4d20ca4
docs(license): translate license to Arabic
RlxChap2 Jun 9, 2026
111900a
docs(webpack-awesome): translate awesome-webpack.mdx files to Arabic
RlxChap2 Jun 9, 2026
c4a15a7
docs(blog): fixed blog translate to Arabic
RlxChap2 Jun 9, 2026
9650ab5
docs(ar): translate plugins, contribute, loaders, guide, migrate and …
RlxChap2 Jun 9, 2026
dc04cfd
fix(format): fixed format, conflicts and lint stages
RlxChap2 Jun 9, 2026
2bd6293
Merge branch 'main' into main
RlxChap2 Jun 9, 2026
b48107b
docs(ar): translating and fix main files to arabic
RlxChap2 Jun 9, 2026
85dcb17
fix(ci): update Arabic docs checks
RlxChap2 Jun 9, 2026
cd7afbf
fix(docs): preserve translated heading anchors
RlxChap2 Jun 9, 2026
03d02d0
docs(ar): complete Arabic RTL localization
RlxChap2 Jun 14, 2026
17fd6ac
docs(cypress): fixed cypress e2e
RlxChap2 Jun 14, 2026
bcaef2d
docs(concept): fixed Arabic translation
0xMe2na Jun 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .markdownlint.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"MD034": false,
"MD036": false,
"MD041": false,
"MD060": false,
"MD059": false,
"no-hard-tabs": false,
"whitespace": false
Expand Down
8 changes: 4 additions & 4 deletions cypress/e2e/check-server-side-rendering.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ describe("server side rendered page", () => {
cy.get('head meta[name="description"]').should(
"have.attr",
"content",
"Learn how to bundle a JavaScript application with webpack 5.",
"تعلّم كيفية تجميع تطبيق JavaScript باستخدام webpack 5.",
);
});

it("should find html tag with lang", () => {
cy.visit("/");
cy.get('html[lang="en"]');
cy.get('html[lang="ar"][dir="rtl"]');
});

it("should find meta charset", () => {
Expand All @@ -25,7 +25,7 @@ describe("server side rendered page", () => {
cy.get('head meta[name="description"]').should(
"have.attr",
"content",
"webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset.",
"webpack هو module bundler. هدفه الأساسي حزم ملفات JavaScript لاستخدامها في المتصفح، ويمكنه كذلك تحويل أي resource أو asset تقريبًا وحزمه أو تجهيزه.",
);
});

Expand All @@ -34,6 +34,6 @@ describe("server side rendered page", () => {
cy.title().should("eq", "webpack");

cy.visit("/guides/getting-started/");
cy.title().should("eq", "Getting Started | webpack");
cy.title().should("eq", "البدء | webpack");
});
});
4 changes: 2 additions & 2 deletions cypress/e2e/mobile-and-404.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ describe("Mobile Sidebar", () => {
"sidebar-mobile--visible",
);

cy.get('button[aria-label="Toggle navigation menu"]').click();
cy.get('button[aria-label="فتح قائمة التنقل"]').click();
cy.get(".sidebar-mobile").should("have.class", "sidebar-mobile--visible");

cy.get(".sidebar-mobile__close").click();
Expand All @@ -23,7 +23,7 @@ describe("Mobile Sidebar", () => {
});

it("should close sidebar when clicking outside", () => {
cy.get('button[aria-label="Toggle navigation menu"]').click();
cy.get('button[aria-label="فتح قائمة التنقل"]').click();
// Click to the right of the 300px wide sidebar
cy.get("body").click(350, 500, { force: true });
cy.get(".sidebar-mobile").should(
Expand Down
7 changes: 3 additions & 4 deletions cypress/e2e/offline.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ describe("offline", () => {

it("shows /migrate/ page", () => {
const url = "/migrate/";
const text = "Migrate";
const text = "الترقية";

cy.visit(url);
cy.get("h1").contains(text);
Expand All @@ -63,9 +63,8 @@ describe("offline", () => {
cy.visit(url);
cy.get("h1").contains(text);

// click `guides` link
cy.get('a[title="guides"]').click();
cy.get("h1").contains("Guides");
cy.get('a[title="الأدلة"]').click();
cy.get("h1").contains("الأدلة");
});

it("open print dialog when accessing /printable url", () => {
Expand Down
10 changes: 7 additions & 3 deletions cypress/e2e/page-hash-navigation.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@

describe("Page hash navigation", () => {
it("scrolls to the element specified by the hash", () => {
cy.visit("/guides/getting-started/#basic-setup");
const hash = encodeURI("#الإعداد-الأساسي");

cy.location("hash").should("eq", "#basic-setup");
cy.visit(`/guides/getting-started/${hash}`);

cy.get("#basic-setup", { timeout: 10000 })
cy.location("hash").then((locationHash) => {
expect(locationHash).to.equal(hash);
});

cy.get(`[id="${hash.slice(1)}"]`, { timeout: 10000 })
.should("exist")
.then(($el) => {
const rect = $el[0].getBoundingClientRect();
Expand Down
14 changes: 9 additions & 5 deletions cypress/e2e/scroll.cy.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
"use strict";

const sizes = ["iphone-6", "macbook-15"];
const basicSetupHash = encodeURI("#الإعداد-الأساسي");
const compileInMemoryHash = encodeURI("#الترجمة-في-الذاكرة");
const developmentHash = encodeURI("#التطوير");
const generalHash = encodeURI("#عام");

describe("Scroll Test", () => {
for (const size of sizes) {
Expand All @@ -10,7 +14,7 @@ describe("Scroll Test", () => {
// scroll to Contributors section
cy.get('[data-testid="contributors"]').scrollIntoView();

cy.isNotInViewport("#basic-setup");
cy.isNotInViewport(`[id="${basicSetupHash.slice(1)}"]`);

cy.visit("/guides/build-performance/");
cy.isNotInViewport('[data-testid="contributors"]');
Expand All @@ -20,10 +24,10 @@ describe("Scroll Test", () => {
cy.visit("/guides/getting-started");
cy.get('[data-testid="contributors"]').scrollIntoView();

cy.visit("/guides/build-performance/#development");
// since we lazy load notification bar now, #development element is a little out of viewport now
cy.isInViewport("#compile-in-memory");
cy.isNotInViewport("#general");
cy.visit(`/guides/build-performance/${developmentHash}`);
// since we lazy load notification bar now, #التطوير element is a little out of viewport now
cy.isInViewport(`[id="${compileInMemoryHash.slice(1)}"]`);
cy.isNotInViewport(`[id="${generalHash.slice(1)}"]`);
});
}
});
1 change: 1 addition & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export default defineConfig([
extends: [configs["browser/recommended-outdated-module"]],
files: [
"src/components/**/*.{js,jsx}",
"src/config/site.js",
"src/utilities/test-local-storage.js",
"src/*.jsx",
"src/sw.js",
Expand Down
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@
"main": "n/a",
"scripts": {
"clean-dist": "rimraf ./dist",
"clean-printable": "rimraf \"src/content/**/printable.mdx\"",
"clean-printable": "rimraf --glob \"src/content/**/printable.mdx\"",
"preclean": "run-s clean-dist clean-printable",
"clean": "rimraf \"src/content/**/_*.mdx\" \"src/**/_*.json\" \"repositories/*.json\"",
"clean": "rimraf --glob \"src/content/**/_*.mdx\" \"src/**/_*.json\" \"repositories/*.json\"",
"start": "npm run clean-dist && webpack serve --config webpack.dev.mjs --env dev --progress --config-node-env development",
"content": "node src/scripts/build-content-tree.mjs ./src/content ./src/_content.json",
"bundle-analyze": "run-s clean fetch content && webpack --config webpack.prod.mjs --config-node-env production && run-s printable content && webpack --config webpack.ssg.mjs --config-node-env production --env ssg --profile --json > stats.json && webpack-bundle-analyzer stats.json",
Expand All @@ -43,15 +43,15 @@
"lint": "run-s lint:*",
"lint:prettier": "prettier --cache --list-different --ignore-unknown .",
"lint:js": "eslint --cache --cache-location .cache/.eslintcache .",
"lint:markdown": "markdownlint --config ./.markdownlint.json --rules ./src/utilities/markdown-lint-enforce-lang-aliases.js '**/*.{md,mdx}'",
"lint:markdown": "markdownlint --config ./.markdownlint.json --rules ./src/utilities/markdown-lint-enforce-lang-aliases.js --ignore \"src/content/**/printable.mdx\" --ignore \"src/content/**/_*.mdx\" --ignore \"src/content/contribute/Governance-*.mdx\" \"**/*.{md,mdx}\"",
"lint:prose": "vale --config='.vale.ini' src/content",
"lint:links": "hyperlink -c 8 --root dist -r dist/index.html --canonicalroot https://webpack.js.org/ --internal --skip /plugins/extract-text-webpack-plugin/ --skip /printable --skip /contribute/Governance --skip https:// --skip http:// --skip sw.js --skip /vendor > internal-links.tap; cat internal-links.tap | tap-spot",
"sitemap": "cd dist && sitemap-static --ignore-file=../sitemap-ignore.json --pretty --prefix=https://webpack.js.org/ > sitemap.xml",
"rss": "node src/scripts/generate-rss.mjs",
"serve": "npm run build && sirv start ./dist --port 4000",
"preprintable": "npm run clean-printable",
"printable": "node ./src/scripts/concatenate-docs.mjs",
"jest": "NODE_OPTIONS=--experimental-vm-modules jest --config=jest.config.mjs",
"jest": "node --experimental-vm-modules ./node_modules/jest/bin/jest.js --config=jest.config.mjs",
"cypress:open": "cypress open",
"cypress:run": "cypress run --browser chrome",
"prettier": "prettier --cache --write --ignore-unknown .",
Expand Down
8 changes: 4 additions & 4 deletions src/components/CodeBlockWithCopy/CodeBlockWithCopy.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -131,13 +131,13 @@ export default function CodeBlockWithCopy({ children }) {
? "bg-red-500 hover:bg-red-700"
: "bg-[#175d96] hover:bg-[#2f85d0]",
)}
aria-label="Copy code to clipboard"
aria-label="نسخ الكود إلى الحافظة"
>
{copyStatus === "copied"
? "Copied!"
? "تم النسخ"
: copyStatus === "error"
? "Error"
: "Copy"}
? "تعذر النسخ"
: "نسخ"}
</button>

<pre ref={preRef}>{children}</pre>
Expand Down
4 changes: 2 additions & 2 deletions src/components/Dropdown/Dropdown.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export default function Dropdown({ className = "", items = [] }) {
ref={dropdownButtonRef}
aria-haspopup="true"
aria-expanded={String(active)}
aria-label="Select language"
aria-label="اختيار اللغة"
onClick={handleClick}
className="cursor-pointer text-white border-none bg-transparent m-0 p-0 text-[length:inherit] flex items-center"
>
Expand Down Expand Up @@ -141,7 +141,7 @@ export default function Dropdown({ className = "", items = [] }) {
href={item.url}
className="block min-w-[88px] px-3 py-1 text-center text-white transition-colors duration-[200ms] visited:text-white hover:bg-[#175d96] hover:text-white focus:bg-[#175d96] focus:text-white"
>
<span lang={item.lang} className="align-top text-left">
<span lang={item.lang} className="align-top text-start">
{item.title}
</span>
</a>
Expand Down
13 changes: 7 additions & 6 deletions src/components/Dropdown/Dropdown.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const items = [
{ title: "French", url: "/fr/", lang: "fr" },
{ title: "Spanish", url: "/es/", lang: "es" },
];
const languageButtonName = /اختيار اللغة/;

function getListWrapper(container) {
return container.querySelector("ul").closest("div");
Expand All @@ -24,7 +25,7 @@ describe("Dropdown", () => {
it("renders the toggle button", () => {
render(<Dropdown items={items} />);
expect(
screen.getByRole("button", { name: /select language/i }),
screen.getByRole("button", { name: languageButtonName }),
).toBeTruthy();
});

Expand Down Expand Up @@ -52,7 +53,7 @@ describe("Dropdown", () => {

it("toggles dropdown on button click", () => {
const { container } = render(<Dropdown items={items} />);
const button = screen.getByRole("button", { name: /select language/i });
const button = screen.getByRole("button", { name: languageButtonName });

fireEvent.click(button);
expect(getListWrapper(container).classList.contains("hidden")).toBe(false);
Expand All @@ -63,7 +64,7 @@ describe("Dropdown", () => {

it("sets aria-expanded correctly", () => {
render(<Dropdown items={items} />);
const button = screen.getByRole("button", { name: /select language/i });
const button = screen.getByRole("button", { name: languageButtonName });

expect(button.getAttribute("aria-expanded")).toBe("false");
fireEvent.click(button);
Expand All @@ -79,7 +80,7 @@ describe("Dropdown", () => {

it("closes on Escape key", () => {
const { container } = render(<Dropdown items={items} />);
const button = screen.getByRole("button", { name: /select language/i });
const button = screen.getByRole("button", { name: languageButtonName });

fireEvent.click(button);
expect(getListWrapper(container).classList.contains("hidden")).toBe(false);
Expand All @@ -95,7 +96,7 @@ describe("Dropdown", () => {

it("closes when clicking outside", () => {
const { container } = render(<Dropdown items={items} />);
const button = screen.getByRole("button", { name: /select language/i });
const button = screen.getByRole("button", { name: languageButtonName });

fireEvent.click(button);
expect(getListWrapper(container).classList.contains("hidden")).toBe(false);
Expand All @@ -109,7 +110,7 @@ describe("Dropdown", () => {

it("does not close dropdown when arrow keys are pressed", () => {
const { container } = render(<Dropdown items={items} />);
const button = screen.getByRole("button", { name: /select language/i });
const button = screen.getByRole("button", { name: languageButtonName });
fireEvent.click(button);

const links = screen.getAllByRole("link");
Expand Down
8 changes: 4 additions & 4 deletions src/components/Dropdown/__snapshots__/Dropdown.test.jsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ exports[`Dropdown matches snapshot 1`] = `
<button
aria-expanded="false"
aria-haspopup="true"
aria-label="Select language"
aria-label="اختيار اللغة"
class="cursor-pointer text-white border-none bg-transparent m-0 p-0 text-[length:inherit] flex items-center"
>
<svg
Expand Down Expand Up @@ -62,7 +62,7 @@ exports[`Dropdown matches snapshot 1`] = `
href="/en/"
>
<span
class="align-top text-left"
class="align-top text-start"
lang="en"
>
English
Expand All @@ -77,7 +77,7 @@ exports[`Dropdown matches snapshot 1`] = `
href="/fr/"
>
<span
class="align-top text-left"
class="align-top text-start"
lang="fr"
>
French
Expand All @@ -92,7 +92,7 @@ exports[`Dropdown matches snapshot 1`] = `
href="/es/"
>
<span
class="align-top text-left"
class="align-top text-start"
lang="es"
>
Spanish
Expand Down
Loading