戰爭爆發前,鑒于中越兩國的特殊關系及法國侵略越南給中國造成的嚴重威脅,再加上左宗棠、張之洞等主戰派的強烈呼吁,清政府表面上一改往日的消極態度,一方面敦促李鴻章抓緊和法國談判,另一方面增強了原駐北圻的桂軍(廣西清軍)兵力,又命云南方面派兵出境,互為聲援,并派人聯絡黑旗軍援越抗法。但是,清政府知道自己的實力不濟,再三訓令清軍不得主動出擊,不得尋釁。這種自相矛盾的舉措,大大便利了法國的侵略部署。
1883年12月初,北圻法軍已增加到近萬人,大部分集中在河內地區,作戰準備基本就緒。而此時清軍方面,負責北圻東線防務的廣西巡撫徐延旭托病滯留諒山,所屬四十四營一萬五千六百人,分駐北寧、太原、高平、諒山等地。其中左路統領廣西提督黃桂蘭、右路統領廣西道員趙沃共率二十五營九千六百人守北寧。后又新招募擴編十九營六千人。
負責西線防務的云貴總督岑毓英雖然奉命力保紅河中游戰略要地山西,但尚未啟程,進駐山西的滇軍僅有三個營,加上劉永福率領的黑旗軍(十二營三千五人)和吏部主事唐景崧率領的少量桂軍(二營八百人),山西守軍共約五千人。
(一)山西失守
山西位于河內以西九十多里,是控制紅河中上游的戰略要地,也是清軍聯系東西線的主要通道。
劉永福在1883年9月11日率領黑旗軍退守山西后,一直在不斷地加強城防和沿岸河堤工事。劉永福命令部眾加固城墻,從河岸到城北門筑起五重木柵,在河岸修筑炮臺,每隔十丈放置一門鐵炮,并在水面設木排、竹筏阻塞河道。城北為主要防御方向,集中黑旗軍六營、桂軍一營占據既設陣地,以控制河道,阻止敵人向北門進攻;城東也是重點防御方向,由黑旗軍五營組成兩道陣地,防敵陸路向東門攻擊;唐景崧商調滇軍督帶張永清率三營由興化到山西,防守西門;黑旗軍一營、桂軍一營配置于南門,以備機動;黃佐炎越軍部署在南門外鄉村中,相機策應。劉永福駐外城,唐景崧駐內城,督戰指揮。
12月11日,法軍新任遠征軍總司令孤拔率領六千多人,分水陸兩路從河內出發向山西進軍。一路由軍艦十二艘,板船四十艘,載陸軍三千二百余人,溯紅河西上;另一路陸軍兩千六百余人沿紅河南岸直撲山西。
14日上午9時,法軍向山西城發起進攻,摧毀沿岸炮臺,并在城東北方向登岸,登岸步兵迅速展開,向黑旗軍陣地接近。黑旗軍依托河堤陣地進行還擊,使法軍遭受嚴重損失而不能及時發起沖擊。下午,劉永福調來東門的黑旗軍主力,隱蔽地迂回到法軍的左側,并插入法軍艦隊與步兵之間,猛烈攻擊法軍側翼,使其兩面受擊,而法軍艦炮則不敢開炮射擊。孤拔見形勢危急,立即令法軍轉入防御,集中所有炮兵向迂回的黑旗軍轟擊。黑旗軍迂回部隊由于傷亡較大被迫撤退。下午4時,孤拔下達攻擊令,法軍向堅守河堤的黑旗軍發起猛烈攻擊。黑旗軍頑強扼守陣地,以排槍射擊大量殺傷敵人,迫使余敵潰退。法軍大炮猛轟,步兵多次進行沖擊。當法軍迫近河堤時,黑旗軍與敵人展開激烈的肉搏戰。經過一個多小時的激戰,法軍以死傷士兵二百人、軍官二十二人的代價奪取了河堤陣地。15日1時,唐景崧組織桂軍和滇軍乘夜進行反擊,企圖奪回陣地,但激戰四小時仍未能獲得成功。于是將城北守軍撤至外城,依托土圍分段堅守。15日上午雙方調整部署。午后,法軍開始向城西運動,企圖奪取城西滇軍據點,然后從城北、城西同時攻城。劉永福判明情況后,率黑旗軍主力增援西門,并加強防御工事。這一天,法軍大炮不停地轟擊山西城。16日拂曉,法軍多次猛攻北門,均未得逞。但守軍傷亡較大,彈藥告竭。法軍同時進攻西門,炮火猛烈。西門城墻最終被法軍炸毀。越奸阮廷潤等人叛國投敵,其余越軍也貪生怕死,穿上白衣,打開城門向法軍投降。危急之下,劉永福、唐景崧督軍堅守到深夜,不得已各自率軍退出山西,轉至興化。26日,山西淪陷。
山西的首戰失利,使清軍失去了威脅河內的前哨陣地,丟掉了控制紅河的戰略要點,北寧亦失犄角之勢。滇軍隨即撤出興化、宣光,使滇桂聯系全斷,東西兩線協同作戰增加了更大困難。這樣,清軍在越南北圻作戰便受到了嚴重影響。
(二)北寧失守
北寧是清軍在越南北圻所據守的戰略要地。
北寧守軍經過一年多的準備,工事不斷加強,兵力逐步增加,到戰役開始前,總兵力已達五十八營兩萬四千余人。其兵力部署是:副將黨敏宣率八營防守北寧東六十余里之三江口,以阻法軍溯六頭江包抄北寧后路;總兵陳德貴率四營,扼守北寧東北之扶朗,以阻止敵艦船沿江進攻涌球威脅北寧;副將韋和禮率十營分守北寧東南之桂陽、左河,劉永福黑旗軍十二營守攬山,阻敵陸路主力進攻北寧;總兵陳德朝率兵八營駐守北寧南五十余里之新河口和慈山,以阻敵沿慈山大路進攻北寧;參將李應章率一營防守北寧以西之金英,以扼山西入北寧之通道;總兵陳朝綱率兩營防守北寧城北八里之涌球(涌球北面臨河,有兩座土山,是北寧的屏障和安危相關要點);副將周炳林率四營防守涌球東五里之塞河處,以阻法軍沿河而上,攻擊涌球;黃桂蘭、趙沃率親兵兩營、參將蔣大章率一營另兩哨防守北寧城池。此外,為保持與諒山的聯系,在北寧與諒山之間的諒江部署有五營。
山西失陷后,北寧受到法軍來自海陽、河內、山西三個方向的嚴重威脅。因此清廷十分驚恐,多次下達諭旨,要防軍固守北寧。但統帥徐延旭老邁昏庸,剛愎自用,對現代戰爭的戰略戰術一無所知。他在清流派人物的吹噓薦舉下,受到清政府破格提拔,騙得了巡撫高官之后,即致電清廷告病,以種種借口拒絕親臨北寧前線,后來在清廷的多次催促之下才勉強出關,駐守諒山。徐延旭把北寧的作戰指揮權交給了左路統領廣西提督黃桂蘭,和右路統領廣西道員趙沃。黃桂蘭雖然是行伍出身,但他的部隊裝備落伍,火炮數量少,步兵中只有部分士兵使用進口或仿制的比較先進的步槍,且子彈稀缺;不少士兵仍使用刀矛、鳥槍、土槍等雜式武器。趙沃不僅昏庸無識,而且年老多病,在形勢緊張時,多次上書稱病告假,但卻受到徐延旭的信任。黃、趙二人地位相當,互不相讓,因此左、右兩路軍互不統屬,各成系統,此乃兵家之大忌。況且,前線的將領們此時已經被上面的政策弄糊涂了,不知道到底是和還是戰,他們以為駐軍只是擺擺樣子而已,生怕自己的挑釁壞了和議大局,因此備戰并不認真。
1884年2月,米樂接替孤拔成為法國遠征軍少將總司令,率領一萬六千人進軍北寧,意圖把中國軍隊徹底趕出越南。
3月7日,米樂、波里也率第一旅六千余人渡過紅河,8日以一部兵力由嘉林佯渡新河,制造出法軍沿慈山大路向北寧進攻的假象,主力則沿新河南岸向東疾馳;同日,尼格里率第二旅六千余人、艦船二十余艘,從海陽出發沿太平江北上,上午9時開始攻擊扶朗,清軍陳德貴等營被法軍包圍。黃昏時分,陳德貴等營沖出敵圍,敗退六七里,扶朗失陷。
9—11日雙方調整部署,清軍將扶朗戰場上敗退下來的四營兵力重新做了部署,但沒有增派兵力加強涌球水路的防御。此時,法軍陸路進攻部隊完成了準備。